diff options
-rw-r--r-- | doc/ext_ffi_semantics.html | 14 | ||||
-rw-r--r-- | src/lj_cconv.c | 5 |
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. | |||
517 | Depending on the use case, you may need to explicitly add a | 517 | Depending 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 | ||
522 | name (as a string key) in the table. Each non-<tt>nil</tt> value is | ||
523 | used to initialize the corresponding field.</li> | ||
524 | |||
525 | <li>Otherwise a <tt>struct</tt>/<tt>union</tt> is initialized in the | ||
526 | order of the declaration of its fields. Each field is initialized with | 521 | order of the declaration of its fields. Each field is initialized with |
527 | the consecutive table elements, starting at either index <tt>[0]</tt> | 522 | consecutive table elements, starting at either index <tt>[0]</tt> |
528 | or <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table | 523 | or <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table |
529 | element.</li> | 524 | element.</li> |
530 | 525 | ||
526 | <li>Otherwise, if neither index <tt>[0]</tt> nor <tt>[1]</tt> is present, | ||
527 | a <tt>struct</tt>/<tt>union</tt> is initialized by looking up each field | ||
528 | name (as a string key) in the table. Each non-<tt>nil</tt> value is | ||
529 | used 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 |
532 | bytes, except for the trailing VLA of a VLS.</li> | 532 | bytes, 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 | ||