From: Michael Wallner Date: Fri, 11 Dec 2015 20:15:04 +0000 (+0100) Subject: flush X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=commitdiff_plain;h=58066949f02dbdbc3ba7b3fa3a0e01836fa72663 flush --- diff --git a/php_psi.h b/php_psi.h index dd422b7..31de919 100644 --- a/php_psi.h +++ b/php_psi.h @@ -60,76 +60,12 @@ void psi_to_object(zval *return_value, set_value *set, impl_val *ret_val); void psi_call(zend_execute_data *execute_data, zval *return_value, impl *impl); -static inline int psi_calc_num_exp_value(num_exp *exp, impl_val *val) { - switch (exp->t) { - case PSI_T_NUMBER: - switch (is_numeric_string(exp->u.numb, strlen(exp->u.numb), (zend_long *) val, (double *) val, 0)) { - case IS_LONG: - return PSI_T_INT64; - case IS_DOUBLE: - return PSI_T_DOUBLE; - } - break; - - case PSI_T_NSNAME: - switch (exp->u.cnst->type->type) { - case PSI_T_INT: - val->i64 = zend_get_constant_str(exp->u.cnst->name, strlen(exp->u.cnst->name))->value.lval; - return PSI_T_INT64; - case PSI_T_FLOAT: - val->dval = zend_get_constant_str(exp->u.cnst->name, strlen(exp->u.cnst->name))->value.dval; - return PSI_T_DOUBLE; - default: - return 0; - } - break; - - case PSI_T_NAME: - switch (real_decl_type(exp->u.dvar->arg->type)->type) { - case PSI_T_INT8: - case PSI_T_UINT8: - case PSI_T_INT16: - case PSI_T_UINT16: - case PSI_T_INT32: - case PSI_T_UINT32: - case PSI_T_INT64: - case PSI_T_UINT64: - memcpy(val, deref_impl_val(exp->u.dvar->arg->let->ptr, exp->u.dvar), sizeof(*val)); - return real_decl_type(exp->u.dvar->arg->type)->type; - - case PSI_T_FLOAT: - case PSI_T_DOUBLE: - memcpy(val, deref_impl_val(exp->u.dvar->arg->let->ptr, exp->u.dvar), sizeof(*val)); - return real_decl_type(exp->u.dvar->arg->type)->type; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - break; +int psi_calc_num_exp(num_exp *exp, impl_val *ref, impl_val *res); - EMPTY_SWITCH_DEFAULT_CASE(); - } - return 0; -} - -static inline int psi_calc_num_exp(num_exp *exp, impl_val *val) { - impl_val num = {0}; - int num_type = psi_calc_num_exp_value(exp, &num); - - if (exp->operand) { - impl_val tmp = {0}; - int tmp_type = psi_calc_num_exp(exp->operand, &tmp); - - return exp->calculator(num_type, &num, tmp_type, &tmp, val); - } - - memcpy(val, &num, sizeof(*val)); - return num_type; -} - -static inline zend_long psi_long_num_exp(num_exp *exp) { +static inline zend_long psi_long_num_exp(num_exp *exp, impl_val *ref) { impl_val val = {0}; - switch (psi_calc_num_exp(exp, &val)) { + switch (psi_calc_num_exp(exp, ref, &val)) { case PSI_T_UINT8: val.u16 = val.u8; case PSI_T_UINT16: val.u32 = val.u16; case PSI_T_UINT32: val.u64 = val.u32; @@ -144,6 +80,11 @@ static inline zend_long psi_long_num_exp(num_exp *exp) { } } +int psi_calc_add(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res); +int psi_calc_sub(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res); +int psi_calc_mul(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res); +int psi_calc_div(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res); + ZEND_BEGIN_MODULE_GLOBALS(psi) char *engine; char *directory; diff --git a/psi.d/glob.psi b/psi.d/glob.psi index 2bb952e..02d1c3d 100644 --- a/psi.d/glob.psi +++ b/psi.d/glob.psi @@ -9,7 +9,7 @@ function psi\glob(string $pattern, int $flags, array &$glob = NULL) : int { to_int(gl_pathc), to_int(gl_offs), to_int(gl_flags), - to_array(**gl_pathv, gl_pathc, gl_offs, to_string(*gl_pathv)) + to_array(**gl_pathv, gl_pathc + gl_offs, to_string(*gl_pathv)) ); free globfree(buf); } diff --git a/src/context.c b/src/context.c index 1e8204a..7f491b8 100644 --- a/src/context.c +++ b/src/context.c @@ -418,6 +418,62 @@ static inline decl_arg *locate_struct_member(decl_struct *s, decl_var *var) { return NULL; } +static inline constant *locate_num_exp_constant(num_exp *exp, constants *consts) { + size_t i; + + for (i = 0; i < consts->count; ++i) { + constant *cnst = consts->list[i]; + + if (!strcmp(cnst->name, exp->u.numb)) { + free(exp->u.numb); + return exp->u.cnst = cnst; + } + } + + return NULL; +} +static inline int validate_num_exp(PSI_Data *data, decl_args *dargs, num_exp *exp) { + if (exp->operand) { + switch (exp->operator) { + case PSI_T_PLUS: + exp->calculator = psi_calc_add; + break; + case PSI_T_MINUS: + exp->calculator = psi_calc_sub; + break; + case PSI_T_ASTERISK: + exp->calculator = psi_calc_mul; + break; + case PSI_T_SLASH: + exp->calculator = psi_calc_div; + break; + EMPTY_SWITCH_DEFAULT_CASE(); + } + if (!validate_num_exp(data, dargs, exp->operand)) { + return 0; + } + } + switch (exp->t) { + case PSI_T_NAME: + if (!locate_decl_var_arg(exp->u.dvar, dargs)) { + data->error(PSI_WARNING, "Unknown variable '%s' in numeric expression", + exp->u.dvar->name); + return 0; + } + return 1; + case PSI_T_NSNAME: + if (!locate_num_exp_constant(exp, data->consts)) { + data->error(PSI_WARNING, "Unknown constant '%s' in numeric expression", + exp->u.numb); + return 0; + } + return 1; + case PSI_T_NUMBER: + return 1; + default: + return 0; + } +} static inline int validate_set_value(PSI_Data *data, set_value *set, decl_arg *ref, decl_args *ref_list) { size_t i; decl_type *ref_type = real_decl_type(ref->type); @@ -465,6 +521,11 @@ static inline int validate_set_value(PSI_Data *data, set_value *set, decl_arg *r return 0; } } + if (set->num) { + if (!validate_num_exp(data, ref_list, set->num)) { + return 0; + } + } if (ref_type->type == PSI_T_STRUCT) { /* to_array(struct, to_...) */ @@ -548,42 +609,7 @@ static inline int validate_impl_ret_stmt(PSI_Data *data, impl *impl) { return 1; } -static inline constant *locate_num_exp_constant(num_exp *exp, constants *consts) { - size_t i; - - for (i = 0; i < consts->count; ++i) { - constant *cnst = consts->list[i]; - if (!strcmp(cnst->name, exp->u.numb)) { - free(exp->u.numb); - return exp->u.cnst = cnst; - } - } - - return NULL; -} -static inline int validate_num_exp(PSI_Data *data, impl *impl, num_exp *exp) { - switch (exp->t) { - case PSI_T_NAME: - if (!locate_decl_var_arg(exp->u.dvar, impl->decl->args)) { - data->error(PSI_WARNING, "Unknown variable '%s' in numeric expression" - " of implementation '%s'", exp->u.dvar->name, impl->func->name); - return 0; - } - return 1; - case PSI_T_NSNAME: - if (!locate_num_exp_constant(exp, data->consts)) { - data->error(PSI_WARNING, "Unknown constant '%s' in numeric expression" - " of implementation '%s'", exp->u.numb, impl->func->name); - return 0; - } - return 1; - case PSI_T_NUMBER: - return 1; - default: - return 0; - } -} static inline int validate_impl_let_stmts(PSI_Data *data, impl *impl) { size_t i, j; /* we can have multiple let stmts */ @@ -615,10 +641,10 @@ static inline int validate_impl_let_stmts(PSI_Data *data, impl *impl) { int check = 0; if (let->val && let->val->func && let->val->func->alloc) { - if (!validate_num_exp(data, impl, let->val->func->alloc->nmemb)) { + if (!validate_num_exp(data, impl->decl->args, let->val->func->alloc->nmemb)) { return 0; } - if (!validate_num_exp(data, impl, let->val->func->alloc->size)) { + if (!validate_num_exp(data, impl->decl->args, let->val->func->alloc->size)) { return 0; } } diff --git a/src/module.c b/src/module.c index 873d56b..4a5aa3e 100644 --- a/src/module.c +++ b/src/module.c @@ -359,16 +359,6 @@ void *psi_array_to_struct(decl_struct *s, HashTable *arr) return mem; } -static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) { - void *ptr = (char *) struct_ptr->ptr + set_arg->layout->pos; - impl_val *val = enref_impl_val(ptr, set_arg->var); - - if (val != ptr) { - *to_free = val; - } - - return val; -} void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) { size_t i; @@ -431,12 +421,12 @@ void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) } else if (set->vars->count > 1) { /* to_array(arr_var, cnt_var[, cnt_var...], to_int(*arr_var)) * check for length in second var - */ + * / size_t count = 0; zval ele; if (set->outer.set) { - /* struct */ + /* struct *//* for (i = 1; i < set->vars->count; ++i) { impl_val *tmp = NULL, *cnt_val; decl_var *cnt_var = set->vars->vars[i]; @@ -456,6 +446,20 @@ void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) size_t size = psi_t_size(var->arg->var->pointer_level ? PSI_T_POINTER : t); impl_val *ptr = iterate(ret_val, size, i, &tmp); + set->inner[0]->func->handler(&ele, set->inner[0], ptr); + add_next_index_zval(return_value, &ele); + } + */ + } else if (set->num) { + /* to_array(arr_var, num_expr, to_int(*arr_var)) + */ + zval ele; + zend_long i, n = psi_long_num_exp(set->num, r_val); + + for (i = 0; i < n; ++i) { + size_t size = psi_t_size(var->arg->var->pointer_level ? PSI_T_POINTER : t); + impl_val *ptr = iterate(ret_val, size, i, &tmp); + set->inner[0]->func->handler(&ele, set->inner[0], ptr); add_next_index_zval(return_value, &ele); } @@ -552,7 +556,7 @@ static inline ZEND_RESULT_CODE psi_parse_args(zend_execute_data *execute_data, i static inline void *psi_do_calloc(let_calloc *alloc) { - zend_long n = psi_long_num_exp(alloc->nmemb), s = psi_long_num_exp(alloc->size); + zend_long n = psi_long_num_exp(alloc->nmemb, NULL), s = psi_long_num_exp(alloc->size, NULL); void *mem = safe_emalloc(n, s, sizeof(void *)); memset(mem, 0, n * s + sizeof(void *)); return mem; @@ -729,134 +733,221 @@ static inline void psi_do_clean(impl *impl) } } +static inline int psi_calc_num_exp_value(num_exp *exp, impl_val *ref, impl_val *res) { + impl_val *tmp = NULL; -#define PSI_CALC_OP(var) res->var = PSI_CALC(v1->var, v2->var) -#define PSI_CALC_OP2(vres, var1, var2) res->vres = PSI_CALC(v1->var1, v2->var2) - -int psi_calc_plus(unsigned char t1, impl_val *v1, unsigned char t2, impl_val *v2, impl_val *res) -{ -#undef PSI_CALC -#define PSI_CALC(var1, var2) (var1) + (var2) - if (t1 == t2) { - switch (t1) { - case PSI_T_FLOAT: PSI_CALC_OP(fval); break; - case PSI_T_DOUBLE: PSI_CALC_OP(dval); break; - case PSI_T_INT8: PSI_CALC_OP(i8); break; - case PSI_T_UINT8: PSI_CALC_OP(u8); break; - case PSI_T_INT16: PSI_CALC_OP(i16); break; - case PSI_T_UINT16: PSI_CALC_OP(u16); break; - case PSI_T_INT32: PSI_CALC_OP(i32); break; - case PSI_T_UINT32: PSI_CALC_OP(u32); break; - case PSI_T_INT64: PSI_CALC_OP(i64); break; - case PSI_T_UINT64: PSI_CALC_OP(u64); break; - EMPTY_SWITCH_DEFAULT_CASE(); - } - return t1; - } else if (t1 == PSI_T_DOUBLE) { - switch (t2) { - case PSI_T_FLOAT: PSI_CALC_OP2(dval, dval, fval); break; - case PSI_T_INT8: PSI_CALC_OP2(dval, dval, i8); break; - case PSI_T_UINT8: PSI_CALC_OP2(dval, dval, u8); break; - case PSI_T_INT16: PSI_CALC_OP2(dval, dval, i16); break; - case PSI_T_UINT16: PSI_CALC_OP2(dval, dval, u16); break; - case PSI_T_INT32: PSI_CALC_OP2(dval, dval, i32); break; - case PSI_T_UINT32: PSI_CALC_OP2(dval, dval, u32); break; - case PSI_T_INT64: PSI_CALC_OP2(dval, dval, i64); break; - case PSI_T_UINT64: PSI_CALC_OP2(dval, dval, u64); break; - EMPTY_SWITCH_DEFAULT_CASE(); + switch (exp->t) { + case PSI_T_NUMBER: + switch (is_numeric_string(exp->u.numb, strlen(exp->u.numb), (zend_long *) res, (double *) res, 0)) { + case IS_LONG: + return PSI_T_INT64; + case IS_DOUBLE: + return PSI_T_DOUBLE; } - return t1; - } else if (t2 == PSI_T_DOUBLE) { - switch (t1) { - case PSI_T_FLOAT: PSI_CALC_OP2(dval, fval, dval); break; - case PSI_T_INT8: PSI_CALC_OP2(dval, i8, dval); break; - case PSI_T_UINT8: PSI_CALC_OP2(dval, u8, dval); break; - case PSI_T_INT16: PSI_CALC_OP2(dval, i16, dval); break; - case PSI_T_UINT16: PSI_CALC_OP2(dval, u16, dval); break; - case PSI_T_INT32: PSI_CALC_OP2(dval, i32, dval); break; - case PSI_T_UINT32: PSI_CALC_OP2(dval, u32, dval); break; - case PSI_T_INT64: PSI_CALC_OP2(dval, i64, dval); break; - case PSI_T_UINT64: PSI_CALC_OP2(dval, u64, dval); break; - EMPTY_SWITCH_DEFAULT_CASE(); - } - return t2; - } else if (t1 == PSI_T_FLOAT) { - switch (t2) { - case PSI_T_DOUBLE: PSI_CALC_OP2(dval, fval, dval); return t2; - case PSI_T_INT8: PSI_CALC_OP2(fval, fval, i8); break; - case PSI_T_UINT8: PSI_CALC_OP2(fval, fval, u8); break; - case PSI_T_INT16: PSI_CALC_OP2(fval, fval, i16); break; - case PSI_T_UINT16: PSI_CALC_OP2(fval, fval, u16); break; - case PSI_T_INT32: PSI_CALC_OP2(fval, fval, i32); break; - case PSI_T_UINT32: PSI_CALC_OP2(fval, fval, u32); break; - case PSI_T_INT64: PSI_CALC_OP2(fval, fval, i64); break; - case PSI_T_UINT64: PSI_CALC_OP2(fval, fval, u64); break; - EMPTY_SWITCH_DEFAULT_CASE(); - } - return t1; - } else if (t2 == PSI_T_FLOAT) { - switch (t1) { - case PSI_T_DOUBLE: PSI_CALC_OP2(dval, dval, fval); return t1; - case PSI_T_INT8: PSI_CALC_OP2(fval, i8, fval); break; - case PSI_T_UINT8: PSI_CALC_OP2(fval, u8, fval); break; - case PSI_T_INT16: PSI_CALC_OP2(fval, i16, fval); break; - case PSI_T_UINT16: PSI_CALC_OP2(fval, u16, fval); break; - case PSI_T_INT32: PSI_CALC_OP2(fval, i32, fval); break; - case PSI_T_UINT32: PSI_CALC_OP2(fval, u32, fval); break; - case PSI_T_INT64: PSI_CALC_OP2(fval, i64, fval); break; - case PSI_T_UINT64: PSI_CALC_OP2(fval, u64, fval); break; - EMPTY_SWITCH_DEFAULT_CASE(); + break; + + case PSI_T_NSNAME: + switch (exp->u.cnst->type->type) { + case PSI_T_INT: + res->i64 = zend_get_constant_str(exp->u.cnst->name, strlen(exp->u.cnst->name))->value.lval; + return PSI_T_INT64; + case PSI_T_FLOAT: + res->dval = zend_get_constant_str(exp->u.cnst->name, strlen(exp->u.cnst->name))->value.dval; + return PSI_T_DOUBLE; + default: + return 0; } - return t2; - } else { - int64_t sval1 = v1->i64, sval2 = v2->i64; - uint64_t uval1 = v1->u64, uval2 = v2->u64; + break; - switch (t1) { - case PSI_T_INT8: sval1 >>= 8; - case PSI_T_INT16: sval1 >>= 8; - case PSI_T_INT32: sval1 >>= 8; + case PSI_T_NAME: + if (exp->u.dvar->arg->let) { + ref = exp->u.dvar->arg->let->ptr; + } else { + ref = struct_member_ref(exp->u.dvar->arg, ref, &tmp); + } + switch (real_decl_type(exp->u.dvar->arg->type)->type) { + case PSI_T_INT8: + case PSI_T_UINT8: + case PSI_T_INT16: + case PSI_T_UINT16: + case PSI_T_INT32: + case PSI_T_UINT32: case PSI_T_INT64: - switch (t2) { - case PSI_T_INT8: sval2 >>= 8; - case PSI_T_INT16: sval2 >>= 8; - case PSI_T_INT32: sval2 >>= 8; - case PSI_T_INT64: - res->i64 = PSI_CALC(sval1 , sval2); - return PSI_T_INT64; - case PSI_T_UINT8: uval2 >>= 8; - case PSI_T_UINT16: uval2 >>= 8; - case PSI_T_UINT32: uval2 >>= 8; - case PSI_T_UINT64: - res->i64 = PSI_CALC(sval1, uval2); - return PSI_T_INT64; - } - break; - case PSI_T_UINT8: uval1 >>= 8; - case PSI_T_UINT16: uval1 >>= 8; - case PSI_T_UINT32: uval1 >>= 8; case PSI_T_UINT64: - switch (t2) { - case PSI_T_INT8: sval2 >>= 8; - case PSI_T_INT16: sval2 >>= 8; - case PSI_T_INT32: sval2 >>= 8; - case PSI_T_INT64: - res->i64 = PSI_CALC(uval1, sval2); - return PSI_T_INT64; - case PSI_T_UINT8: uval2 >>= 8; - case PSI_T_UINT16: uval2 >>= 8; - case PSI_T_UINT32: uval2 >>= 8; - case PSI_T_UINT64: - res->u64 = PSI_CALC(uval1, uval2); - return PSI_T_UINT64; + memcpy(res, deref_impl_val(ref, exp->u.dvar), sizeof(*res)); + if (tmp) { + free(tmp); } - break; + return real_decl_type(exp->u.dvar->arg->type)->type; + + case PSI_T_FLOAT: + case PSI_T_DOUBLE: + memcpy(res, deref_impl_val(ref, exp->u.dvar), sizeof(*res)); + if (tmp) { + free(tmp); + } + return real_decl_type(exp->u.dvar->arg->type)->type; + + EMPTY_SWITCH_DEFAULT_CASE(); } + break; + + EMPTY_SWITCH_DEFAULT_CASE(); } - ZEND_ASSERT(0); - return 0; + return 0; } +int psi_calc_num_exp(num_exp *exp, impl_val *ref, impl_val *res) { + impl_val num = {0}; + int num_type = psi_calc_num_exp_value(exp, ref, &num); + + if (exp->operand) { + impl_val tmp = {0}; + int tmp_type = psi_calc_num_exp(exp->operand, ref, &tmp); + + return exp->calculator(num_type, &num, tmp_type, &tmp, res); + } + + memcpy(res, &num, sizeof(*res)); + return num_type; +} + +#define PSI_CALC_OP(var) res->var = PSI_CALC(v1->var, v2->var) +#define PSI_CALC_OP2(vres, var1, var2) res->vres = PSI_CALC(v1->var1, v2->var2) +#define PSI_CALC_FN(op) int psi_calc_##op(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res) \ +{ \ + if (t1 == t2) { \ + switch (t1) { \ + case PSI_T_FLOAT: PSI_CALC_OP(fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP(dval); break; \ + case PSI_T_INT8: PSI_CALC_OP(i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP(u8); break; \ + case PSI_T_INT16: PSI_CALC_OP(i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP(u16); break; \ + case PSI_T_INT32: PSI_CALC_OP(i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP(u32); break; \ + case PSI_T_INT64: PSI_CALC_OP(i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP(u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + return t1; \ + } else if (t1 == PSI_T_DOUBLE) { \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(dval, dval, fval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(dval, dval, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(dval, dval, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(dval, dval, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(dval, dval, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(dval, dval, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(dval, dval, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(dval, dval, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(dval, dval, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + return t1; \ + } else if (t2 == PSI_T_DOUBLE) { \ + switch (t1) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(dval, fval, dval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(dval, i8, dval); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(dval, u8, dval); break; \ + case PSI_T_INT16: PSI_CALC_OP2(dval, i16, dval); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(dval, u16, dval); break; \ + case PSI_T_INT32: PSI_CALC_OP2(dval, i32, dval); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(dval, u32, dval); break; \ + case PSI_T_INT64: PSI_CALC_OP2(dval, i64, dval); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(dval, u64, dval); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + return t2; \ + } else if (t1 == PSI_T_FLOAT) { \ + switch (t2) { \ + case PSI_T_DOUBLE: PSI_CALC_OP2(dval, fval, dval); return t2; \ + case PSI_T_INT8: PSI_CALC_OP2(fval, fval, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(fval, fval, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(fval, fval, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(fval, fval, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(fval, fval, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(fval, fval, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(fval, fval, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(fval, fval, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + return t1; \ + } else if (t2 == PSI_T_FLOAT) { \ + switch (t1) { \ + case PSI_T_DOUBLE: PSI_CALC_OP2(dval, dval, fval); return t1; \ + case PSI_T_INT8: PSI_CALC_OP2(fval, i8, fval); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(fval, u8, fval); break; \ + case PSI_T_INT16: PSI_CALC_OP2(fval, i16, fval); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(fval, u16, fval); break; \ + case PSI_T_INT32: PSI_CALC_OP2(fval, i32, fval); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(fval, u32, fval); break; \ + case PSI_T_INT64: PSI_CALC_OP2(fval, i64, fval); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(fval, u64, fval); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + return t2; \ + } else { \ + int64_t sval1 = v1->i64, sval2 = v2->i64; \ + uint64_t uval1 = v1->u64, uval2 = v2->u64; \ + switch (t1) { \ + case PSI_T_INT8: sval1 >>= 8; \ + case PSI_T_INT16: sval1 >>= 8; \ + case PSI_T_INT32: sval1 >>= 8; \ + case PSI_T_INT64: \ + switch (t2) { \ + case PSI_T_INT8: sval2 >>= 8; \ + case PSI_T_INT16: sval2 >>= 8; \ + case PSI_T_INT32: sval2 >>= 8; \ + case PSI_T_INT64: \ + res->i64 = PSI_CALC(sval1 , sval2); \ + return PSI_T_INT64; \ + case PSI_T_UINT8: uval2 >>= 8; \ + case PSI_T_UINT16: uval2 >>= 8; \ + case PSI_T_UINT32: uval2 >>= 8; \ + case PSI_T_UINT64: \ + res->i64 = PSI_CALC(sval1, uval2); \ + return PSI_T_INT64; \ + } \ + break; \ + case PSI_T_UINT8: uval1 >>= 8; \ + case PSI_T_UINT16: uval1 >>= 8; \ + case PSI_T_UINT32: uval1 >>= 8; \ + case PSI_T_UINT64: \ + switch (t2) { \ + case PSI_T_INT8: sval2 >>= 8; \ + case PSI_T_INT16: sval2 >>= 8; \ + case PSI_T_INT32: sval2 >>= 8; \ + case PSI_T_INT64: \ + res->i64 = PSI_CALC(uval1, sval2); \ + return PSI_T_INT64; \ + case PSI_T_UINT8: uval2 >>= 8; \ + case PSI_T_UINT16: uval2 >>= 8; \ + case PSI_T_UINT32: uval2 >>= 8; \ + case PSI_T_UINT64: \ + res->u64 = PSI_CALC(uval1, uval2); \ + return PSI_T_UINT64; \ + } \ + break; \ + } \ + } \ + ZEND_ASSERT(0); \ + return 0; \ +} + +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) + (var2) +PSI_CALC_FN(add) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) * (var2) +PSI_CALC_FN(mul) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) - (var2) +PSI_CALC_FN(sub) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) / (var2) +PSI_CALC_FN(div) + void psi_call(zend_execute_data *execute_data, zval *return_value, impl *impl) { impl_val ret_val; diff --git a/src/parser.h b/src/parser.h index 28f436f..2e551dc 100644 --- a/src/parser.h +++ b/src/parser.h @@ -728,6 +728,7 @@ static inline void free_set_func(set_func *func) { typedef struct set_value { set_func *func; decl_vars *vars; + num_exp *num; struct { struct set_value *set; impl_val *val; @@ -1012,6 +1013,16 @@ static void free_impls(impls *impls) { free(impls); } +static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) { + void *ptr = (char *) struct_ptr->ptr + set_arg->layout->pos; + impl_val *val = enref_impl_val(ptr, set_arg->var); + + if (val != ptr) { + *to_free = val; + } + + return val; +} #define PSI_ERROR 16 #define PSI_WARNING 32 diff --git a/src/parser_proc.y b/src/parser_proc.y index 0dc928f..c90062a 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -412,13 +412,23 @@ set_stmt(set) ::= SET impl_var(var) EQUALS set_value(val) EOS. { %type set_value {set_value*} %destructor set_value {free_set_value($$);} -set_value(val) ::= set_func(func) LPAREN decl_vars(vars) RPAREN. { - val = init_set_value(func, vars); +set_value(val) ::= set_func(func) LPAREN decl_var(var) RPAREN. { + val = init_set_value(func, init_decl_vars(var)); } -set_value(val) ::= set_func(func_) LPAREN decl_vars(vars_) COMMA set_vals(vals) RPAREN. { +set_value(val) ::= set_func(func) LPAREN decl_var(var) COMMA num_exp(num_) RPAREN. { + val = init_set_value(func, init_decl_vars(var)); + val->num = num_; +} +set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA set_vals(vals) RPAREN. { + val = vals; + val->func = func_; + val->vars = init_decl_vars(var); +} +set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA num_exp(num_) COMMA set_vals(vals) RPAREN. { val = vals; val->func = func_; - val->vars = vars_; + val->num = num_; + val->vars = init_decl_vars(var); } %type set_vals {set_value*} %destructor set_vals {free_set_value($$);} diff --git a/tests/pipe/pipe.psi b/tests/pipe/pipe.psi index deb11d0..fd7e3ff 100644 --- a/tests/pipe/pipe.psi +++ b/tests/pipe/pipe.psi @@ -3,6 +3,6 @@ extern int pipe(int fds[2]); function \pipe(array &$fds = null) : int { return to_int(pipe); - let fds = calloc(2, int); + let fds = calloc(2, psi\SIZEOF_INT); set $fds = to_array(fds[2]); }