aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/ext_ffi_semantics.html14
-rw-r--r--src/lj_cconv.c5
2 files changed, 10 insertions, 9 deletions
diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html
index bf9f9bee..30aa9648 100644
--- a/doc/ext_ffi_semantics.html
+++ b/doc/ext_ffi_semantics.html
@@ -517,17 +517,17 @@ A VLA is only initialized with the element(s) given in the table.
517Depending on the use case, you may need to explicitly add a 517Depending on the use case, you may need to explicitly add a
518<tt>NULL</tt> or <tt>0</tt> terminator to a VLA.</li> 518<tt>NULL</tt> or <tt>0</tt> terminator to a VLA.</li>
519 519
520<li>If the table has a non-empty hash part, a 520<li>A <tt>struct</tt>/<tt>union</tt> can be initialized in the
521<tt>struct</tt>/<tt>union</tt> is initialized by looking up each field
522name (as a string key) in the table. Each non-<tt>nil</tt> value is
523used to initialize the corresponding field.</li>
524
525<li>Otherwise a <tt>struct</tt>/<tt>union</tt> is initialized in the
526order of the declaration of its fields. Each field is initialized with 521order of the declaration of its fields. Each field is initialized with
527the consecutive table elements, starting at either index <tt>[0]</tt> 522consecutive table elements, starting at either index <tt>[0]</tt>
528or <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table 523or <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table
529element.</li> 524element.</li>
530 525
526<li>Otherwise, if neither index <tt>[0]</tt> nor <tt>[1]</tt> is present,
527a <tt>struct</tt>/<tt>union</tt> is initialized by looking up each field
528name (as a string key) in the table. Each non-<tt>nil</tt> value is
529used to initialize the corresponding field.</li>
530
531<li>Uninitialized fields of a <tt>struct</tt> are filled with zero 531<li>Uninitialized fields of a <tt>struct</tt> are filled with zero
532bytes, except for the trailing VLA of a VLS.</li> 532bytes, except for the trailing VLA of a VLS.</li>
533 533
diff --git a/src/lj_cconv.c b/src/lj_cconv.c
index b81b4e90..7b32e35d 100644
--- a/src/lj_cconv.c
+++ b/src/lj_cconv.c
@@ -493,17 +493,19 @@ static void cconv_substruct_tab(CTState *cts, CType *d, uint8_t *dp,
493 id = df->sib; 493 id = df->sib;
494 if (ctype_isfield(df->info) || ctype_isbitfield(df->info)) { 494 if (ctype_isfield(df->info) || ctype_isbitfield(df->info)) {
495 TValue *tv; 495 TValue *tv;
496 int32_t i = *ip; 496 int32_t i = *ip, iz = i;
497 if (!gcref(df->name)) continue; /* Ignore unnamed fields. */ 497 if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
498 if (i >= 0) { 498 if (i >= 0) {
499 retry: 499 retry:
500 tv = (TValue *)lj_tab_getint(t, i); 500 tv = (TValue *)lj_tab_getint(t, i);
501 if (!tv || tvisnil(tv)) { 501 if (!tv || tvisnil(tv)) {
502 if (i == 0) { i = 1; goto retry; } /* 1-based tables. */ 502 if (i == 0) { i = 1; goto retry; } /* 1-based tables. */
503 if (iz == 0) { *ip = i = -1; goto tryname; } /* Init named fields. */
503 break; /* Stop at first nil. */ 504 break; /* Stop at first nil. */
504 } 505 }
505 *ip = i + 1; 506 *ip = i + 1;
506 } else { 507 } else {
508 tryname:
507 tv = (TValue *)lj_tab_getstr(t, gco2str(gcref(df->name))); 509 tv = (TValue *)lj_tab_getstr(t, gco2str(gcref(df->name)));
508 if (!tv || tvisnil(tv)) continue; 510 if (!tv || tvisnil(tv)) continue;
509 } 511 }
@@ -524,7 +526,6 @@ static void cconv_struct_tab(CTState *cts, CType *d,
524{ 526{
525 int32_t i = 0; 527 int32_t i = 0;
526 memset(dp, 0, d->size); /* Much simpler to clear the struct first. */ 528 memset(dp, 0, d->size); /* Much simpler to clear the struct first. */
527 if (t->hmask) i = -1; else if (t->asize == 0) return; /* Fast exit. */
528 cconv_substruct_tab(cts, d, dp, t, &i, flags); 529 cconv_substruct_tab(cts, d, dp, t, &i, flags);
529} 530}
530 531