X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Flibjit.c;h=7b0a49a5cadd6748edd886ba5345570c9d292ddf;hp=6d55e1a772d8e2ca5cda644449c6286e2e0f3df6;hb=c0999079ea85fecba8ab5eec386541fc1ce733b7;hpb=4ecafb11128dc652013564387ab33b8b9110f039 diff --git a/src/libjit.c b/src/libjit.c index 6d55e1a..7b0a49a 100644 --- a/src/libjit.c +++ b/src/libjit.c @@ -50,6 +50,10 @@ static inline jit_type_t psi_jit_token_type(token_t t) { return jit_type_sys_float; case PSI_T_DOUBLE: return jit_type_sys_double; +#ifdef HAVE_LONG_DOUBLE + case PSI_T_LONG_DOUBLE: + return jit_type_sys_long_double; +#endif case PSI_T_POINTER: return jit_type_void_ptr; } @@ -74,49 +78,53 @@ static void psi_jit_struct_type_dtor(void *type) { jit_type_free(strct); } + +static size_t psi_jit_struct_type_pad(jit_type_t **els, size_t padding) { + size_t i; + + for (i = 0; i < padding; ++i) { + *els++ = jit_type_copy(jit_type_sys_char); + } + + return padding; +} + static unsigned psi_jit_struct_type_elements(decl_struct *strct, jit_type_t **fields) { - size_t i, j, argc = strct->args->count << 2, nels = 0, offset = 0, align, padding; - *fields = calloc(argc, sizeof(*fields)); + size_t i, j, argc = strct->args->count, nels = 0, offset = 0, maxalign; + *fields = calloc(argc + 1, sizeof(*fields)); for (i = 0; i < strct->args->count; ++i) { decl_arg *darg = strct->args->args[i]; jit_type_t type = jit_type_copy(psi_jit_decl_arg_type(darg)); + size_t padding, alignment; - if (darg->layout->pos > offset) { - padding = darg->layout->pos - offset; - align = ((padding - 1) | (jit_type_get_alignment(type) - 1)) + 1; - if (align >= padding) { - padding = 0; - } - } else { - align = 0; - padding = 0; - } + ZEND_ASSERT(jit_type_get_size(type) == darg->layout->len); - if (padding) { - for (j = 0; j < padding; ++j) { - jit_type_t pad = jit_type_copy(jit_type_sys_char); + if ((alignment = jit_type_get_alignment(type)) > maxalign) { + maxalign = alignment; + } - ZEND_ASSERT(nels + 1 < argc); - (*fields)[nels++] = pad; + if ((padding = psi_offset_padding(darg->layout->pos - offset, alignment))) { + if (nels + padding > argc) { + argc += padding; + *fields = realloc(*fields, (argc + 1) * sizeof(*fields)); } + psi_jit_struct_type_pad(&(*fields)[nels], padding); + nels += padding; + offset += padding; } + ZEND_ASSERT(offset == darg->layout->pos); - ZEND_ASSERT(nels + 1 < argc); + offset = (offset + darg->layout->len + alignment - 1) & ~(alignment - 1); (*fields)[nels++] = type; - - offset += MAX(align, padding) + darg->layout->len; } + /* apply struct alignment padding */ + offset = (offset + maxalign - 1) & ~(maxalign - 1); + ZEND_ASSERT(offset <= strct->size); if (offset < strct->size) { - padding = strct->size - offset; - for (j = 0; j < padding; ++j) { - jit_type_t pad = jit_type_copy(jit_type_sys_char); - - ZEND_ASSERT(nels + 1 < argc); - (*fields)[nels++] = pad; - } + nels += psi_jit_struct_type_pad(&(*fields)[nels], strct->size - offset); } return nels;