FFI: Change priority of table initializer variants for structs.

This commit is contained in:
Mike Pall 2012-11-15 00:21:01 +01:00
parent 2689f32453
commit 16f23458bc
2 changed files with 10 additions and 9 deletions

View File

@ -517,17 +517,17 @@ A VLA is only initialized with the element(s) given in the table.
Depending on the use case, you may need to explicitly add a Depending on the use case, you may need to explicitly add a
<tt>NULL</tt> or <tt>0</tt> terminator to a VLA.</li> <tt>NULL</tt> or <tt>0</tt> terminator to a VLA.</li>
<li>If the table has a non-empty hash part, a <li>A <tt>struct</tt>/<tt>union</tt> can be initialized in the
<tt>struct</tt>/<tt>union</tt> is initialized by looking up each field
name (as a string key) in the table. Each non-<tt>nil</tt> value is
used to initialize the corresponding field.</li>
<li>Otherwise a <tt>struct</tt>/<tt>union</tt> is initialized in the
order of the declaration of its fields. Each field is initialized with order of the declaration of its fields. Each field is initialized with
the consecutive table elements, starting at either index <tt>[0]</tt> consecutive table elements, starting at either index <tt>[0]</tt>
or <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table or <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table
element.</li> element.</li>
<li>Otherwise, if neither index <tt>[0]</tt> nor <tt>[1]</tt> is present,
a <tt>struct</tt>/<tt>union</tt> is initialized by looking up each field
name (as a string key) in the table. Each non-<tt>nil</tt> value is
used to initialize the corresponding field.</li>
<li>Uninitialized fields of a <tt>struct</tt> are filled with zero <li>Uninitialized fields of a <tt>struct</tt> are filled with zero
bytes, except for the trailing VLA of a VLS.</li> bytes, except for the trailing VLA of a VLS.</li>

View File

@ -493,17 +493,19 @@ static void cconv_substruct_tab(CTState *cts, CType *d, uint8_t *dp,
id = df->sib; id = df->sib;
if (ctype_isfield(df->info) || ctype_isbitfield(df->info)) { if (ctype_isfield(df->info) || ctype_isbitfield(df->info)) {
TValue *tv; TValue *tv;
int32_t i = *ip; int32_t i = *ip, iz = i;
if (!gcref(df->name)) continue; /* Ignore unnamed fields. */ if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
if (i >= 0) { if (i >= 0) {
retry: retry:
tv = (TValue *)lj_tab_getint(t, i); tv = (TValue *)lj_tab_getint(t, i);
if (!tv || tvisnil(tv)) { if (!tv || tvisnil(tv)) {
if (i == 0) { i = 1; goto retry; } /* 1-based tables. */ if (i == 0) { i = 1; goto retry; } /* 1-based tables. */
if (iz == 0) { *ip = i = -1; goto tryname; } /* Init named fields. */
break; /* Stop at first nil. */ break; /* Stop at first nil. */
} }
*ip = i + 1; *ip = i + 1;
} else { } else {
tryname:
tv = (TValue *)lj_tab_getstr(t, gco2str(gcref(df->name))); tv = (TValue *)lj_tab_getstr(t, gco2str(gcref(df->name)));
if (!tv || tvisnil(tv)) continue; if (!tv || tvisnil(tv)) continue;
} }
@ -524,7 +526,6 @@ static void cconv_struct_tab(CTState *cts, CType *d,
{ {
int32_t i = 0; int32_t i = 0;
memset(dp, 0, d->size); /* Much simpler to clear the struct first. */ memset(dp, 0, d->size); /* Much simpler to clear the struct first. */
if (t->hmask) i = -1; else if (t->asize == 0) return; /* Fast exit. */
cconv_substruct_tab(cts, d, dp, t, &i, flags); cconv_substruct_tab(cts, d, dp, t, &i, flags);
} }