FFI: Simplify initializer rules. Clarify docs.

This commit is contained in:
Mike Pall
2011-01-23 14:23:21 +01:00
parent f529d22869
commit 72b3fff72f
6 changed files with 58 additions and 33 deletions

View File

@@ -679,17 +679,12 @@ static void cconv_struct_init(CTState *cts, CType *d, CTSize sz, uint8_t *dp,
** This is true if an aggregate is to be initialized with a value.
** Valarrays are treated as values here so ct_tv handles (V|C, I|F).
*/
int lj_cconv_multi_init(CTState *cts, CType *d, TValue *o)
int lj_cconv_multi_init(CType *d, TValue *o)
{
if (!(ctype_isrefarray(d->info) || ctype_isstruct(d->info)))
return 0; /* Destination is not an aggregate. */
if (tvistab(o) || (tvisstr(o) && !ctype_isstruct(d->info)))
return 0; /* Initializer is not a value. */
if (tviscdata(o)) {
CTInfo info = lj_ctype_rawref(cts, cdataV(o)->typeid)->info;
if (ctype_isrefarray(info) || ctype_isstruct(info))
return 0; /* Initializer is not a value. */
}
return 1; /* Otherwise the initializer is a value. */
}
@@ -699,7 +694,7 @@ void lj_cconv_ct_init(CTState *cts, CType *d, CTSize sz,
{
if (len == 0)
memset(dp, 0, sz);
else if (len == 1 && !lj_cconv_multi_init(cts, d, o))
else if (len == 1 && !lj_cconv_multi_init(d, o))
lj_cconv_ct_tv(cts, d, dp, o, 0);
else if (ctype_isarray(d->info)) /* Also handles valarray init with len>1. */
cconv_array_init(cts, d, sz, dp, o, len);

View File

@@ -58,7 +58,7 @@ LJ_FUNC int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp);
LJ_FUNC void lj_cconv_ct_tv(CTState *cts, CType *d,
uint8_t *dp, TValue *o, CTInfo flags);
LJ_FUNC void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o);
LJ_FUNC int lj_cconv_multi_init(CTState *cts, CType *d, TValue *o);
LJ_FUNC int lj_cconv_multi_init(CType *d, TValue *o);
LJ_FUNC void lj_cconv_ct_init(CTState *cts, CType *d, CTSize sz,
uint8_t *dp, TValue *o, MSize len);

View File

@@ -566,8 +566,7 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
CType *d = ctype_raw(cts, id);
TRef trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, TREF_NIL);
J->base[0] = trcd;
if (J->base[1] && !J->base[2] &&
!lj_cconv_multi_init(cts, d, &rd->argv[1])) {
if (J->base[1] && !J->base[2] && !lj_cconv_multi_init(d, &rd->argv[1])) {
goto single_init;
} else if (ctype_isarray(d->info)) {
CType *dc = ctype_rawchild(cts, d); /* Array element type. */