lj_ctype.c (18236B)
1 /* 2 ** C type management. 3 ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h 4 */ 5 6 #include "lj_obj.h" 7 8 #if LJ_HASFFI 9 10 #include "lj_gc.h" 11 #include "lj_err.h" 12 #include "lj_str.h" 13 #include "lj_tab.h" 14 #include "lj_strfmt.h" 15 #include "lj_ctype.h" 16 #include "lj_ccallback.h" 17 #include "lj_buf.h" 18 19 /* -- C type definitions -------------------------------------------------- */ 20 21 /* Predefined typedefs. */ 22 #define CTTDDEF(_) \ 23 /* Vararg handling. */ \ 24 _("va_list", P_VOID) \ 25 _("__builtin_va_list", P_VOID) \ 26 _("__gnuc_va_list", P_VOID) \ 27 /* From stddef.h. */ \ 28 _("ptrdiff_t", INT_PSZ) \ 29 _("size_t", UINT_PSZ) \ 30 _("wchar_t", WCHAR) \ 31 /* Subset of stdint.h. */ \ 32 _("int8_t", INT8) \ 33 _("int16_t", INT16) \ 34 _("int32_t", INT32) \ 35 _("int64_t", INT64) \ 36 _("uint8_t", UINT8) \ 37 _("uint16_t", UINT16) \ 38 _("uint32_t", UINT32) \ 39 _("uint64_t", UINT64) \ 40 _("intptr_t", INT_PSZ) \ 41 _("uintptr_t", UINT_PSZ) \ 42 /* From POSIX. */ \ 43 _("ssize_t", INT_PSZ) \ 44 /* End of typedef list. */ 45 46 /* Keywords (only the ones we actually care for). */ 47 #define CTKWDEF(_) \ 48 /* Type specifiers. */ \ 49 _("void", -1, CTOK_VOID) \ 50 _("_Bool", 0, CTOK_BOOL) \ 51 _("bool", 1, CTOK_BOOL) \ 52 _("char", 1, CTOK_CHAR) \ 53 _("int", 4, CTOK_INT) \ 54 _("__int8", 1, CTOK_INT) \ 55 _("__int16", 2, CTOK_INT) \ 56 _("__int32", 4, CTOK_INT) \ 57 _("__int64", 8, CTOK_INT) \ 58 _("float", 4, CTOK_FP) \ 59 _("double", 8, CTOK_FP) \ 60 _("long", 0, CTOK_LONG) \ 61 _("short", 0, CTOK_SHORT) \ 62 _("_Complex", 0, CTOK_COMPLEX) \ 63 _("complex", 0, CTOK_COMPLEX) \ 64 _("__complex", 0, CTOK_COMPLEX) \ 65 _("__complex__", 0, CTOK_COMPLEX) \ 66 _("signed", 0, CTOK_SIGNED) \ 67 _("__signed", 0, CTOK_SIGNED) \ 68 _("__signed__", 0, CTOK_SIGNED) \ 69 _("unsigned", 0, CTOK_UNSIGNED) \ 70 /* Type qualifiers. */ \ 71 _("const", 0, CTOK_CONST) \ 72 _("__const", 0, CTOK_CONST) \ 73 _("__const__", 0, CTOK_CONST) \ 74 _("volatile", 0, CTOK_VOLATILE) \ 75 _("__volatile", 0, CTOK_VOLATILE) \ 76 _("__volatile__", 0, CTOK_VOLATILE) \ 77 _("restrict", 0, CTOK_RESTRICT) \ 78 _("__restrict", 0, CTOK_RESTRICT) \ 79 _("__restrict__", 0, CTOK_RESTRICT) \ 80 _("inline", 0, CTOK_INLINE) \ 81 _("__inline", 0, CTOK_INLINE) \ 82 _("__inline__", 0, CTOK_INLINE) \ 83 /* Storage class specifiers. */ \ 84 _("typedef", 0, CTOK_TYPEDEF) \ 85 _("extern", 0, CTOK_EXTERN) \ 86 _("static", 0, CTOK_STATIC) \ 87 _("auto", 0, CTOK_AUTO) \ 88 _("register", 0, CTOK_REGISTER) \ 89 /* GCC Attributes. */ \ 90 _("__extension__", 0, CTOK_EXTENSION) \ 91 _("__attribute", 0, CTOK_ATTRIBUTE) \ 92 _("__attribute__", 0, CTOK_ATTRIBUTE) \ 93 _("asm", 0, CTOK_ASM) \ 94 _("__asm", 0, CTOK_ASM) \ 95 _("__asm__", 0, CTOK_ASM) \ 96 /* MSVC Attributes. */ \ 97 _("__declspec", 0, CTOK_DECLSPEC) \ 98 _("__cdecl", CTCC_CDECL, CTOK_CCDECL) \ 99 _("__thiscall", CTCC_THISCALL, CTOK_CCDECL) \ 100 _("__fastcall", CTCC_FASTCALL, CTOK_CCDECL) \ 101 _("__stdcall", CTCC_STDCALL, CTOK_CCDECL) \ 102 _("__ptr32", 4, CTOK_PTRSZ) \ 103 _("__ptr64", 8, CTOK_PTRSZ) \ 104 /* Other type specifiers. */ \ 105 _("struct", 0, CTOK_STRUCT) \ 106 _("union", 0, CTOK_UNION) \ 107 _("enum", 0, CTOK_ENUM) \ 108 /* Operators. */ \ 109 _("sizeof", 0, CTOK_SIZEOF) \ 110 _("__alignof", 0, CTOK_ALIGNOF) \ 111 _("__alignof__", 0, CTOK_ALIGNOF) \ 112 /* End of keyword list. */ 113 114 /* Type info for predefined types. Size merged in. */ 115 static CTInfo lj_ctype_typeinfo[] = { 116 #define CTTYINFODEF(id, sz, ct, info) CTINFO((ct),(((sz)&0x3fu)<<10)+(info)), 117 #define CTTDINFODEF(name, id) CTINFO(CT_TYPEDEF, CTID_##id), 118 #define CTKWINFODEF(name, sz, kw) CTINFO(CT_KW,(((sz)&0x3fu)<<10)+(kw)), 119 CTTYDEF(CTTYINFODEF) 120 CTTDDEF(CTTDINFODEF) 121 CTKWDEF(CTKWINFODEF) 122 #undef CTTYINFODEF 123 #undef CTTDINFODEF 124 #undef CTKWINFODEF 125 0 126 }; 127 128 /* Predefined type names collected in a single string. */ 129 static const char * const lj_ctype_typenames = 130 #define CTTDNAMEDEF(name, id) name "\0" 131 #define CTKWNAMEDEF(name, sz, cds) name "\0" 132 CTTDDEF(CTTDNAMEDEF) 133 CTKWDEF(CTKWNAMEDEF) 134 #undef CTTDNAMEDEF 135 #undef CTKWNAMEDEF 136 ; 137 138 #define CTTYPEINFO_NUM (sizeof(lj_ctype_typeinfo)/sizeof(CTInfo)-1) 139 #ifdef LUAJIT_CTYPE_CHECK_ANCHOR 140 #define CTTYPETAB_MIN CTTYPEINFO_NUM 141 #else 142 #define CTTYPETAB_MIN 128 143 #endif 144 145 /* -- C type interning ---------------------------------------------------- */ 146 147 #define ct_hashtype(info, size) (hashrot(info, size) & CTHASH_MASK) 148 #define ct_hashname(name) \ 149 (hashrot(u32ptr(name), u32ptr(name) + HASH_BIAS) & CTHASH_MASK) 150 151 /* Create new type element. */ 152 CTypeID lj_ctype_new(CTState *cts, CType **ctp) 153 { 154 CTypeID id = cts->top; 155 CType *ct; 156 lua_assert(cts->L); 157 if (LJ_UNLIKELY(id >= cts->sizetab)) { 158 if (id >= CTID_MAX) lj_err_msg(cts->L, LJ_ERR_TABOV); 159 #ifdef LUAJIT_CTYPE_CHECK_ANCHOR 160 ct = lj_mem_newvec(cts->L, id+1, CType); 161 memcpy(ct, cts->tab, id*sizeof(CType)); 162 memset(cts->tab, 0, id*sizeof(CType)); 163 lj_mem_freevec(cts->g, cts->tab, cts->sizetab, CType); 164 cts->tab = ct; 165 cts->sizetab = id+1; 166 #else 167 lj_mem_growvec(cts->L, cts->tab, cts->sizetab, CTID_MAX, CType); 168 #endif 169 } 170 cts->top = id+1; 171 *ctp = ct = &cts->tab[id]; 172 ct->info = 0; 173 ct->size = 0; 174 ct->sib = 0; 175 ct->next = 0; 176 setgcrefnull(ct->name); 177 return id; 178 } 179 180 /* Intern a type element. */ 181 CTypeID lj_ctype_intern(CTState *cts, CTInfo info, CTSize size) 182 { 183 uint32_t h = ct_hashtype(info, size); 184 CTypeID id = cts->hash[h]; 185 lua_assert(cts->L); 186 while (id) { 187 CType *ct = ctype_get(cts, id); 188 if (ct->info == info && ct->size == size) 189 return id; 190 id = ct->next; 191 } 192 id = cts->top; 193 if (LJ_UNLIKELY(id >= cts->sizetab)) { 194 if (id >= CTID_MAX) lj_err_msg(cts->L, LJ_ERR_TABOV); 195 lj_mem_growvec(cts->L, cts->tab, cts->sizetab, CTID_MAX, CType); 196 } 197 cts->top = id+1; 198 cts->tab[id].info = info; 199 cts->tab[id].size = size; 200 cts->tab[id].sib = 0; 201 cts->tab[id].next = cts->hash[h]; 202 setgcrefnull(cts->tab[id].name); 203 cts->hash[h] = (CTypeID1)id; 204 return id; 205 } 206 207 /* Add type element to hash table. */ 208 static void ctype_addtype(CTState *cts, CType *ct, CTypeID id) 209 { 210 uint32_t h = ct_hashtype(ct->info, ct->size); 211 ct->next = cts->hash[h]; 212 cts->hash[h] = (CTypeID1)id; 213 } 214 215 /* Add named element to hash table. */ 216 void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id) 217 { 218 uint32_t h = ct_hashname(gcref(ct->name)); 219 ct->next = cts->hash[h]; 220 cts->hash[h] = (CTypeID1)id; 221 } 222 223 /* Get a C type by name, matching the type mask. */ 224 CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name, uint32_t tmask) 225 { 226 CTypeID id = cts->hash[ct_hashname(name)]; 227 while (id) { 228 CType *ct = ctype_get(cts, id); 229 if (gcref(ct->name) == obj2gco(name) && 230 ((tmask >> ctype_type(ct->info)) & 1)) { 231 *ctp = ct; 232 return id; 233 } 234 id = ct->next; 235 } 236 *ctp = &cts->tab[0]; /* Simplify caller logic. ctype_get() would assert. */ 237 return 0; 238 } 239 240 /* Get a struct/union/enum/function field by name. */ 241 CType *lj_ctype_getfieldq(CTState *cts, CType *ct, GCstr *name, CTSize *ofs, 242 CTInfo *qual) 243 { 244 while (ct->sib) { 245 ct = ctype_get(cts, ct->sib); 246 if (gcref(ct->name) == obj2gco(name)) { 247 *ofs = ct->size; 248 return ct; 249 } 250 if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) { 251 CType *fct, *cct = ctype_child(cts, ct); 252 CTInfo q = 0; 253 while (ctype_isattrib(cct->info)) { 254 if (ctype_attrib(cct->info) == CTA_QUAL) q |= cct->size; 255 cct = ctype_child(cts, cct); 256 } 257 fct = lj_ctype_getfieldq(cts, cct, name, ofs, qual); 258 if (fct) { 259 if (qual) *qual |= q; 260 *ofs += ct->size; 261 return fct; 262 } 263 } 264 } 265 return NULL; /* Not found. */ 266 } 267 268 /* -- C type information -------------------------------------------------- */ 269 270 /* Follow references and get raw type for a C type ID. */ 271 CType *lj_ctype_rawref(CTState *cts, CTypeID id) 272 { 273 CType *ct = ctype_get(cts, id); 274 while (ctype_isattrib(ct->info) || ctype_isref(ct->info)) 275 ct = ctype_child(cts, ct); 276 return ct; 277 } 278 279 /* Get size for a C type ID. Does NOT support VLA/VLS. */ 280 CTSize lj_ctype_size(CTState *cts, CTypeID id) 281 { 282 CType *ct = ctype_raw(cts, id); 283 return ctype_hassize(ct->info) ? ct->size : CTSIZE_INVALID; 284 } 285 286 /* Get size for a variable-length C type. Does NOT support other C types. */ 287 CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem) 288 { 289 uint64_t xsz = 0; 290 if (ctype_isstruct(ct->info)) { 291 CTypeID arrid = 0, fid = ct->sib; 292 xsz = ct->size; /* Add the struct size. */ 293 while (fid) { 294 CType *ctf = ctype_get(cts, fid); 295 if (ctype_type(ctf->info) == CT_FIELD) 296 arrid = ctype_cid(ctf->info); /* Remember last field of VLS. */ 297 fid = ctf->sib; 298 } 299 ct = ctype_raw(cts, arrid); 300 } 301 lua_assert(ctype_isvlarray(ct->info)); /* Must be a VLA. */ 302 ct = ctype_rawchild(cts, ct); /* Get array element. */ 303 lua_assert(ctype_hassize(ct->info)); 304 /* Calculate actual size of VLA and check for overflow. */ 305 xsz += (uint64_t)ct->size * nelem; 306 return xsz < 0x80000000u ? (CTSize)xsz : CTSIZE_INVALID; 307 } 308 309 /* Get type, qualifiers, size and alignment for a C type ID. */ 310 CTInfo lj_ctype_info(CTState *cts, CTypeID id, CTSize *szp) 311 { 312 CTInfo qual = 0; 313 CType *ct = ctype_get(cts, id); 314 for (;;) { 315 CTInfo info = ct->info; 316 if (ctype_isenum(info)) { 317 /* Follow child. Need to look at its attributes, too. */ 318 } else if (ctype_isattrib(info)) { 319 if (ctype_isxattrib(info, CTA_QUAL)) 320 qual |= ct->size; 321 else if (ctype_isxattrib(info, CTA_ALIGN) && !(qual & CTFP_ALIGNED)) 322 qual |= CTFP_ALIGNED + CTALIGN(ct->size); 323 } else { 324 if (!(qual & CTFP_ALIGNED)) qual |= (info & CTF_ALIGN); 325 qual |= (info & ~(CTF_ALIGN|CTMASK_CID)); 326 lua_assert(ctype_hassize(info) || ctype_isfunc(info)); 327 *szp = ctype_isfunc(info) ? CTSIZE_INVALID : ct->size; 328 break; 329 } 330 ct = ctype_get(cts, ctype_cid(info)); 331 } 332 return qual; 333 } 334 335 /* Get ctype metamethod. */ 336 cTValue *lj_ctype_meta(CTState *cts, CTypeID id, MMS mm) 337 { 338 CType *ct = ctype_get(cts, id); 339 cTValue *tv; 340 while (ctype_isattrib(ct->info) || ctype_isref(ct->info)) { 341 id = ctype_cid(ct->info); 342 ct = ctype_get(cts, id); 343 } 344 if (ctype_isptr(ct->info) && 345 ctype_isfunc(ctype_get(cts, ctype_cid(ct->info))->info)) 346 tv = lj_tab_getstr(cts->miscmap, &cts->g->strempty); 347 else 348 tv = lj_tab_getinth(cts->miscmap, -(int32_t)id); 349 if (tv && tvistab(tv) && 350 (tv = lj_tab_getstr(tabV(tv), mmname_str(cts->g, mm))) && !tvisnil(tv)) 351 return tv; 352 return NULL; 353 } 354 355 /* -- C type representation ----------------------------------------------- */ 356 357 /* Fixed max. length of a C type representation. */ 358 #define CTREPR_MAX 512 359 360 typedef struct CTRepr { 361 char *pb, *pe; 362 CTState *cts; 363 lua_State *L; 364 int needsp; 365 int ok; 366 char buf[CTREPR_MAX]; 367 } CTRepr; 368 369 /* Prepend string. */ 370 static void ctype_prepstr(CTRepr *ctr, const char *str, MSize len) 371 { 372 char *p = ctr->pb; 373 if (ctr->buf + len+1 > p) { ctr->ok = 0; return; } 374 if (ctr->needsp) *--p = ' '; 375 ctr->needsp = 1; 376 p -= len; 377 while (len-- > 0) p[len] = str[len]; 378 ctr->pb = p; 379 } 380 381 #define ctype_preplit(ctr, str) ctype_prepstr((ctr), "" str, sizeof(str)-1) 382 383 /* Prepend char. */ 384 static void ctype_prepc(CTRepr *ctr, int c) 385 { 386 if (ctr->buf >= ctr->pb) { ctr->ok = 0; return; } 387 *--ctr->pb = c; 388 } 389 390 /* Prepend number. */ 391 static void ctype_prepnum(CTRepr *ctr, uint32_t n) 392 { 393 char *p = ctr->pb; 394 if (ctr->buf + 10+1 > p) { ctr->ok = 0; return; } 395 do { *--p = (char)('0' + n % 10); } while (n /= 10); 396 ctr->pb = p; 397 ctr->needsp = 0; 398 } 399 400 /* Append char. */ 401 static void ctype_appc(CTRepr *ctr, int c) 402 { 403 if (ctr->pe >= ctr->buf + CTREPR_MAX) { ctr->ok = 0; return; } 404 *ctr->pe++ = c; 405 } 406 407 /* Append number. */ 408 static void ctype_appnum(CTRepr *ctr, uint32_t n) 409 { 410 char buf[10]; 411 char *p = buf+sizeof(buf); 412 char *q = ctr->pe; 413 if (q > ctr->buf + CTREPR_MAX - 10) { ctr->ok = 0; return; } 414 do { *--p = (char)('0' + n % 10); } while (n /= 10); 415 do { *q++ = *p++; } while (p < buf+sizeof(buf)); 416 ctr->pe = q; 417 } 418 419 /* Prepend qualifiers. */ 420 static void ctype_prepqual(CTRepr *ctr, CTInfo info) 421 { 422 if ((info & CTF_VOLATILE)) ctype_preplit(ctr, "volatile"); 423 if ((info & CTF_CONST)) ctype_preplit(ctr, "const"); 424 } 425 426 /* Prepend named type. */ 427 static void ctype_preptype(CTRepr *ctr, CType *ct, CTInfo qual, const char *t) 428 { 429 if (gcref(ct->name)) { 430 GCstr *str = gco2str(gcref(ct->name)); 431 ctype_prepstr(ctr, strdata(str), str->len); 432 } else { 433 if (ctr->needsp) ctype_prepc(ctr, ' '); 434 ctype_prepnum(ctr, ctype_typeid(ctr->cts, ct)); 435 ctr->needsp = 1; 436 } 437 ctype_prepstr(ctr, t, (MSize)strlen(t)); 438 ctype_prepqual(ctr, qual); 439 } 440 441 static void ctype_repr(CTRepr *ctr, CTypeID id) 442 { 443 CType *ct = ctype_get(ctr->cts, id); 444 CTInfo qual = 0; 445 int ptrto = 0; 446 for (;;) { 447 CTInfo info = ct->info; 448 CTSize size = ct->size; 449 switch (ctype_type(info)) { 450 case CT_NUM: 451 if ((info & CTF_BOOL)) { 452 ctype_preplit(ctr, "bool"); 453 } else if ((info & CTF_FP)) { 454 if (size == sizeof(double)) ctype_preplit(ctr, "double"); 455 else if (size == sizeof(float)) ctype_preplit(ctr, "float"); 456 else ctype_preplit(ctr, "long double"); 457 } else if (size == 1) { 458 if (!((info ^ CTF_UCHAR) & CTF_UNSIGNED)) ctype_preplit(ctr, "char"); 459 else if (CTF_UCHAR) ctype_preplit(ctr, "signed char"); 460 else ctype_preplit(ctr, "unsigned char"); 461 } else if (size < 8) { 462 if (size == 4) ctype_preplit(ctr, "int"); 463 else ctype_preplit(ctr, "short"); 464 if ((info & CTF_UNSIGNED)) ctype_preplit(ctr, "unsigned"); 465 } else { 466 ctype_preplit(ctr, "_t"); 467 ctype_prepnum(ctr, size*8); 468 ctype_preplit(ctr, "int"); 469 if ((info & CTF_UNSIGNED)) ctype_prepc(ctr, 'u'); 470 } 471 ctype_prepqual(ctr, (qual|info)); 472 return; 473 case CT_VOID: 474 ctype_preplit(ctr, "void"); 475 ctype_prepqual(ctr, (qual|info)); 476 return; 477 case CT_STRUCT: 478 ctype_preptype(ctr, ct, qual, (info & CTF_UNION) ? "union" : "struct"); 479 return; 480 case CT_ENUM: 481 if (id == CTID_CTYPEID) { 482 ctype_preplit(ctr, "ctype"); 483 return; 484 } 485 ctype_preptype(ctr, ct, qual, "enum"); 486 return; 487 case CT_ATTRIB: 488 if (ctype_attrib(info) == CTA_QUAL) qual |= size; 489 break; 490 case CT_PTR: 491 if ((info & CTF_REF)) { 492 ctype_prepc(ctr, '&'); 493 } else { 494 ctype_prepqual(ctr, (qual|info)); 495 if (LJ_64 && size == 4) ctype_preplit(ctr, "__ptr32"); 496 ctype_prepc(ctr, '*'); 497 } 498 qual = 0; 499 ptrto = 1; 500 ctr->needsp = 1; 501 break; 502 case CT_ARRAY: 503 if (ctype_isrefarray(info)) { 504 ctr->needsp = 1; 505 if (ptrto) { ptrto = 0; ctype_prepc(ctr, '('); ctype_appc(ctr, ')'); } 506 ctype_appc(ctr, '['); 507 if (size != CTSIZE_INVALID) { 508 CTSize csize = ctype_child(ctr->cts, ct)->size; 509 ctype_appnum(ctr, csize ? size/csize : 0); 510 } else if ((info & CTF_VLA)) { 511 ctype_appc(ctr, '?'); 512 } 513 ctype_appc(ctr, ']'); 514 } else if ((info & CTF_COMPLEX)) { 515 if (size == 2*sizeof(float)) ctype_preplit(ctr, "float"); 516 ctype_preplit(ctr, "complex"); 517 return; 518 } else { 519 ctype_preplit(ctr, ")))"); 520 ctype_prepnum(ctr, size); 521 ctype_preplit(ctr, "__attribute__((vector_size("); 522 } 523 break; 524 case CT_FUNC: 525 ctr->needsp = 1; 526 if (ptrto) { ptrto = 0; ctype_prepc(ctr, '('); ctype_appc(ctr, ')'); } 527 ctype_appc(ctr, '('); 528 ctype_appc(ctr, ')'); 529 break; 530 default: 531 lua_assert(0); 532 break; 533 } 534 ct = ctype_get(ctr->cts, ctype_cid(info)); 535 } 536 } 537 538 /* Return a printable representation of a C type. */ 539 GCstr *lj_ctype_repr(lua_State *L, CTypeID id, GCstr *name) 540 { 541 global_State *g = G(L); 542 CTRepr ctr; 543 ctr.pb = ctr.pe = &ctr.buf[CTREPR_MAX/2]; 544 ctr.cts = ctype_ctsG(g); 545 ctr.L = L; 546 ctr.ok = 1; 547 ctr.needsp = 0; 548 if (name) ctype_prepstr(&ctr, strdata(name), name->len); 549 ctype_repr(&ctr, id); 550 if (LJ_UNLIKELY(!ctr.ok)) return lj_str_newlit(L, "?"); 551 return lj_str_new(L, ctr.pb, ctr.pe - ctr.pb); 552 } 553 554 /* Convert int64_t/uint64_t to string with 'LL' or 'ULL' suffix. */ 555 GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned) 556 { 557 char buf[1+20+3]; 558 char *p = buf+sizeof(buf); 559 int sign = 0; 560 *--p = 'L'; *--p = 'L'; 561 if (isunsigned) { 562 *--p = 'U'; 563 } else if ((int64_t)n < 0) { 564 n = (uint64_t)-(int64_t)n; 565 sign = 1; 566 } 567 do { *--p = (char)('0' + n % 10); } while (n /= 10); 568 if (sign) *--p = '-'; 569 return lj_str_new(L, p, (size_t)(buf+sizeof(buf)-p)); 570 } 571 572 /* Convert complex to string with 'i' or 'I' suffix. */ 573 GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size) 574 { 575 SBuf *sb = lj_buf_tmp_(L); 576 TValue re, im; 577 if (size == 2*sizeof(double)) { 578 re.n = *(double *)sp; im.n = ((double *)sp)[1]; 579 } else { 580 re.n = (double)*(float *)sp; im.n = (double)((float *)sp)[1]; 581 } 582 lj_strfmt_putfnum(sb, STRFMT_G14, re.n); 583 if (!(im.u32.hi & 0x80000000u) || im.n != im.n) lj_buf_putchar(sb, '+'); 584 lj_strfmt_putfnum(sb, STRFMT_G14, im.n); 585 lj_buf_putchar(sb, sbufP(sb)[-1] >= 'a' ? 'I' : 'i'); 586 return lj_buf_str(L, sb); 587 } 588 589 /* -- C type state -------------------------------------------------------- */ 590 591 /* Initialize C type table and state. */ 592 CTState *lj_ctype_init(lua_State *L) 593 { 594 CTState *cts = lj_mem_newt(L, sizeof(CTState), CTState); 595 CType *ct = lj_mem_newvec(L, CTTYPETAB_MIN, CType); 596 const char *name = lj_ctype_typenames; 597 CTypeID id; 598 memset(cts, 0, sizeof(CTState)); 599 cts->tab = ct; 600 cts->sizetab = CTTYPETAB_MIN; 601 cts->top = CTTYPEINFO_NUM; 602 cts->L = NULL; 603 cts->g = G(L); 604 for (id = 0; id < CTTYPEINFO_NUM; id++, ct++) { 605 CTInfo info = lj_ctype_typeinfo[id]; 606 ct->size = (CTSize)((int32_t)(info << 16) >> 26); 607 ct->info = info & 0xffff03ffu; 608 ct->sib = 0; 609 if (ctype_type(info) == CT_KW || ctype_istypedef(info)) { 610 size_t len = strlen(name); 611 GCstr *str = lj_str_new(L, name, len); 612 ctype_setname(ct, str); 613 name += len+1; 614 lj_ctype_addname(cts, ct, id); 615 } else { 616 setgcrefnull(ct->name); 617 ct->next = 0; 618 if (!ctype_isenum(info)) ctype_addtype(cts, ct, id); 619 } 620 } 621 setmref(G(L)->ctype_state, cts); 622 return cts; 623 } 624 625 /* Free C type table and state. */ 626 void lj_ctype_freestate(global_State *g) 627 { 628 CTState *cts = ctype_ctsG(g); 629 if (cts) { 630 lj_ccallback_mcode_free(cts); 631 lj_mem_freevec(g, cts->tab, cts->sizetab, CType); 632 lj_mem_freevec(g, cts->cb.cbid, cts->cb.sizeid, CTypeID1); 633 lj_mem_freet(g, cts); 634 } 635 } 636 637 #endif