mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-04-18 21:19:19 +00:00
Compare commits
3 Commits
f15ddc92e9
...
9cb1ba9d35
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9cb1ba9d35 | ||
![]() |
538a82133a | ||
![]() |
6a079a441b |
@ -179,7 +179,7 @@ static const void *bcread_varinfo(GCproto *pt)
|
||||
}
|
||||
|
||||
/* Read a single constant key/value of a template table. */
|
||||
static void bcread_ktabk(LexState *ls, TValue *o)
|
||||
static void bcread_ktabk(LexState *ls, TValue *o, GCtab *t)
|
||||
{
|
||||
MSize tp = bcread_uleb128(ls);
|
||||
if (tp >= BCDUMP_KTAB_STR) {
|
||||
@ -191,6 +191,8 @@ static void bcread_ktabk(LexState *ls, TValue *o)
|
||||
} else if (tp == BCDUMP_KTAB_NUM) {
|
||||
o->u32.lo = bcread_uleb128(ls);
|
||||
o->u32.hi = bcread_uleb128(ls);
|
||||
} else if (t && tp == BCDUMP_KTAB_NIL) { /* Restore nil value marker. */
|
||||
settabV(ls->L, o, t);
|
||||
} else {
|
||||
lj_assertLS(tp <= BCDUMP_KTAB_TRUE, "bad constant type %d", tp);
|
||||
setpriV(o, ~tp);
|
||||
@ -207,15 +209,15 @@ static GCtab *bcread_ktab(LexState *ls)
|
||||
MSize i;
|
||||
TValue *o = tvref(t->array);
|
||||
for (i = 0; i < narray; i++, o++)
|
||||
bcread_ktabk(ls, o);
|
||||
bcread_ktabk(ls, o, NULL);
|
||||
}
|
||||
if (nhash) { /* Read hash entries. */
|
||||
MSize i;
|
||||
for (i = 0; i < nhash; i++) {
|
||||
TValue key;
|
||||
bcread_ktabk(ls, &key);
|
||||
bcread_ktabk(ls, &key, NULL);
|
||||
lj_assertLS(!tvisnil(&key), "nil key");
|
||||
bcread_ktabk(ls, lj_tab_set(ls->L, t, &key));
|
||||
bcread_ktabk(ls, lj_tab_set(ls->L, t, &key), t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
|
@ -71,6 +71,8 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
|
||||
*p++ = BCDUMP_KTAB_NUM;
|
||||
p = lj_strfmt_wuleb128(p, o->u32.lo);
|
||||
p = lj_strfmt_wuleb128(p, o->u32.hi);
|
||||
} else if (tvistab(o)) { /* Write the nil value marker as a nil. */
|
||||
*p++ = BCDUMP_KTAB_NIL;
|
||||
} else {
|
||||
lj_assertBCW(tvispri(o), "unhandled type %d", itype(o));
|
||||
*p++ = BCDUMP_KTAB_NIL+~itype(o);
|
||||
@ -133,7 +135,7 @@ static void bcwrite_ktab_sorted_hash(BCWriteCtx *ctx, Node *node, MSize nhash)
|
||||
TValue **heap = ctx->heap;
|
||||
MSize i = nhash;
|
||||
for (;; node--) { /* Build heap. */
|
||||
if (!tvisnil(&node->key)) {
|
||||
if (!tvisnil(&node->val)) {
|
||||
bcwrite_ktabk_heap_insert(heap, --i, nhash, &node->key);
|
||||
if (i == 0) break;
|
||||
}
|
||||
@ -163,7 +165,7 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
|
||||
MSize i, hmask = t->hmask;
|
||||
Node *node = noderef(t->node);
|
||||
for (i = 0; i <= hmask; i++)
|
||||
nhash += !tvisnil(&node[i].key);
|
||||
nhash += !tvisnil(&node[i].val);
|
||||
}
|
||||
/* Write number of array slots and hash slots. */
|
||||
p = lj_strfmt_wuleb128(p, narray);
|
||||
@ -184,7 +186,7 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
|
||||
} else {
|
||||
MSize i = nhash;
|
||||
for (;; node--)
|
||||
if (!tvisnil(&node->key)) {
|
||||
if (!tvisnil(&node->val)) {
|
||||
bcwrite_ktabk(ctx, &node->key, 0);
|
||||
bcwrite_ktabk(ctx, &node->val, 1);
|
||||
if (--i == 0) break;
|
||||
|
120
src/lj_cparse.c
120
src/lj_cparse.c
@ -182,6 +182,7 @@ static CPToken cp_number(CPState *cp)
|
||||
else if (!(cp->mode & CPARSE_MODE_SKIP))
|
||||
cp_errmsg(cp, CTOK_INTEGER, LJ_ERR_XNUMBER);
|
||||
cp->val.u32 = (uint32_t)o.i;
|
||||
cp->val.imm = 1;
|
||||
return CTOK_INTEGER;
|
||||
}
|
||||
|
||||
@ -191,6 +192,7 @@ static CPToken cp_ident(CPState *cp)
|
||||
do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
|
||||
cp->str = lj_buf_str(cp->L, &cp->sb);
|
||||
cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask);
|
||||
cp->val.imm = 0;
|
||||
if (ctype_type(cp->ct->info) == CT_KW)
|
||||
return ctype_cid(cp->ct->info);
|
||||
return CTOK_IDENT;
|
||||
@ -209,11 +211,13 @@ static CPToken cp_param(CPState *cp)
|
||||
if (tvisstr(o)) {
|
||||
cp->str = strV(o);
|
||||
cp->val.id = 0;
|
||||
cp->val.imm = 0;
|
||||
cp->ct = &cp->cts->tab[0];
|
||||
return CTOK_IDENT;
|
||||
} else if (tvisnumber(o)) {
|
||||
cp->val.i32 = numberVint(o);
|
||||
cp->val.id = CTID_INT32;
|
||||
cp->val.imm = 1;
|
||||
return CTOK_INTEGER;
|
||||
} else {
|
||||
GCcdata *cd;
|
||||
@ -224,6 +228,7 @@ static CPToken cp_param(CPState *cp)
|
||||
cp->val.id = *(CTypeID *)cdataptr(cd);
|
||||
else
|
||||
cp->val.id = cd->ctypeid;
|
||||
cp->val.imm = 0;
|
||||
return '$';
|
||||
}
|
||||
}
|
||||
@ -281,6 +286,7 @@ static CPToken cp_string(CPState *cp)
|
||||
if (sbuflen(&cp->sb) != 1) cp_err_token(cp, '\'');
|
||||
cp->val.i32 = (int32_t)(char)*cp->sb.b;
|
||||
cp->val.id = CTID_INT32;
|
||||
cp->val.imm = 1;
|
||||
return CTOK_INTEGER;
|
||||
}
|
||||
}
|
||||
@ -478,6 +484,7 @@ static void cp_expr_sizeof(CPState *cp, CPValue *k, int wantsz)
|
||||
k->u32 = 1u << ctype_align(info);
|
||||
}
|
||||
k->id = CTID_UINT32; /* Really size_t. */
|
||||
k->imm = 1;
|
||||
}
|
||||
|
||||
/* Parse prefix operators. */
|
||||
@ -509,22 +516,25 @@ static void cp_expr_prefix(CPState *cp, CPValue *k)
|
||||
ct = lj_ctype_rawref(cp->cts, k->id);
|
||||
if (!ctype_ispointer(ct->info))
|
||||
cp_err_badidx(cp, ct);
|
||||
k->u32 = 0; k->id = ctype_cid(ct->info);
|
||||
k->u32 = 0; k->id = ctype_cid(ct->info); k->imm = 0;
|
||||
} else if (cp_opt(cp, '&')) { /* Address operator. */
|
||||
cp_expr_unary(cp, k);
|
||||
k->id = lj_ctype_intern(cp->cts, CTINFO(CT_PTR, CTALIGN_PTR+k->id),
|
||||
CTSIZE_PTR);
|
||||
k->imm = 0;
|
||||
} else if (cp_opt(cp, CTOK_SIZEOF)) {
|
||||
cp_expr_sizeof(cp, k, 1);
|
||||
} else if (cp_opt(cp, CTOK_ALIGNOF)) {
|
||||
cp_expr_sizeof(cp, k, 0);
|
||||
} else if (cp->tok == CTOK_IDENT) {
|
||||
if (ctype_type(cp->ct->info) == CT_CONSTVAL) {
|
||||
k->u32 = cp->ct->size; k->id = ctype_cid(cp->ct->info);
|
||||
k->u32 = cp->ct->size; k->id = ctype_cid(cp->ct->info); k->imm = 1;
|
||||
} else if (ctype_type(cp->ct->info) == CT_EXTERN) {
|
||||
k->u32 = cp->val.id; k->id = ctype_cid(cp->ct->info);
|
||||
k->u32 = cp->val.id; k->id = ctype_cid(cp->ct->info); k->imm = 0;
|
||||
} else if (ctype_type(cp->ct->info) == CT_FUNC) {
|
||||
k->u32 = cp->val.id; k->id = cp->val.id;
|
||||
k->u32 = cp->val.id; k->id = cp->val.id; k->imm = 0;
|
||||
} else if (ctype_type(cp->ct->info) == CT_FIELD) {
|
||||
k->u32 = cp->ct->size; k->id = ctype_cid(cp->ct->info); k->imm = 0;
|
||||
} else {
|
||||
goto err_expr;
|
||||
}
|
||||
@ -535,6 +545,7 @@ static void cp_expr_prefix(CPState *cp, CPValue *k)
|
||||
sz += cp->str->len;
|
||||
k->u32 = sz + 1;
|
||||
k->id = CTID_A_CCHAR;
|
||||
k->imm = 0;
|
||||
} else {
|
||||
err_expr:
|
||||
cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
|
||||
@ -557,6 +568,7 @@ static void cp_expr_postfix(CPState *cp, CPValue *k)
|
||||
}
|
||||
cp_check(cp, ']');
|
||||
k->u32 = 0;
|
||||
k->imm = 0;
|
||||
} else if (cp->tok == '.' || cp->tok == CTOK_DEREF) { /* Struct deref. */
|
||||
CTSize ofs;
|
||||
CType *fct;
|
||||
@ -575,7 +587,8 @@ static void cp_expr_postfix(CPState *cp, CPValue *k)
|
||||
cp_errmsg(cp, 0, LJ_ERR_FFI_BADMEMBER, strdata(s), strdata(cp->str));
|
||||
}
|
||||
ct = fct;
|
||||
k->u32 = ctype_isconstval(ct->info) ? ct->size : 0;
|
||||
k->imm = ctype_isconstval(ct->info);
|
||||
k->u32 = k->imm ? ct->size : 0;
|
||||
cp_next(cp);
|
||||
} else {
|
||||
return;
|
||||
@ -599,19 +612,20 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
|
||||
cp_expr_sub(cp, &k3, 0);
|
||||
k->u32 = k->u32 ? k2.u32 : k3.u32;
|
||||
k->id = k2.id > k3.id ? k2.id : k3.id;
|
||||
k->imm = k->imm && (k->u32 ? k2.imm : k3.imm);
|
||||
continue;
|
||||
}
|
||||
/* fallthrough */
|
||||
case 1:
|
||||
if (cp_opt(cp, CTOK_OROR)) {
|
||||
cp_expr_sub(cp, &k2, 2); k->i32 = k->u32 || k2.u32; k->id = CTID_INT32;
|
||||
continue;
|
||||
goto arith_imm;
|
||||
}
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
if (cp_opt(cp, CTOK_ANDAND)) {
|
||||
cp_expr_sub(cp, &k2, 3); k->i32 = k->u32 && k2.u32; k->id = CTID_INT32;
|
||||
continue;
|
||||
goto arith_imm;
|
||||
}
|
||||
/* fallthrough */
|
||||
case 3:
|
||||
@ -632,10 +646,10 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
|
||||
case 6:
|
||||
if (cp_opt(cp, CTOK_EQ)) {
|
||||
cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 == k2.u32; k->id = CTID_INT32;
|
||||
continue;
|
||||
goto arith_imm;
|
||||
} else if (cp_opt(cp, CTOK_NE)) {
|
||||
cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 != k2.u32; k->id = CTID_INT32;
|
||||
continue;
|
||||
goto arith_imm;
|
||||
}
|
||||
/* fallthrough */
|
||||
case 7:
|
||||
@ -646,7 +660,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
|
||||
else
|
||||
k->i32 = k->u32 < k2.u32;
|
||||
k->id = CTID_INT32;
|
||||
continue;
|
||||
goto arith_imm;
|
||||
} else if (cp_opt(cp, '>')) {
|
||||
cp_expr_sub(cp, &k2, 8);
|
||||
if (k->id == CTID_INT32 && k2.id == CTID_INT32)
|
||||
@ -654,7 +668,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
|
||||
else
|
||||
k->i32 = k->u32 > k2.u32;
|
||||
k->id = CTID_INT32;
|
||||
continue;
|
||||
goto arith_imm;
|
||||
} else if (cp_opt(cp, CTOK_LE)) {
|
||||
cp_expr_sub(cp, &k2, 8);
|
||||
if (k->id == CTID_INT32 && k2.id == CTID_INT32)
|
||||
@ -662,7 +676,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
|
||||
else
|
||||
k->i32 = k->u32 <= k2.u32;
|
||||
k->id = CTID_INT32;
|
||||
continue;
|
||||
goto arith_imm;
|
||||
} else if (cp_opt(cp, CTOK_GE)) {
|
||||
cp_expr_sub(cp, &k2, 8);
|
||||
if (k->id == CTID_INT32 && k2.id == CTID_INT32)
|
||||
@ -670,20 +684,20 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
|
||||
else
|
||||
k->i32 = k->u32 >= k2.u32;
|
||||
k->id = CTID_INT32;
|
||||
continue;
|
||||
goto arith_imm;
|
||||
}
|
||||
/* fallthrough */
|
||||
case 8:
|
||||
if (cp_opt(cp, CTOK_SHL)) {
|
||||
cp_expr_sub(cp, &k2, 9); k->u32 = k->u32 << k2.u32;
|
||||
continue;
|
||||
goto arith_imm;
|
||||
} else if (cp_opt(cp, CTOK_SHR)) {
|
||||
cp_expr_sub(cp, &k2, 9);
|
||||
if (k->id == CTID_INT32)
|
||||
k->i32 = k->i32 >> k2.i32;
|
||||
else
|
||||
k->u32 = k->u32 >> k2.u32;
|
||||
continue;
|
||||
goto arith_imm;
|
||||
}
|
||||
/* fallthrough */
|
||||
case 9:
|
||||
@ -691,6 +705,8 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
|
||||
cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 + k2.u32;
|
||||
arith_result:
|
||||
if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */
|
||||
arith_imm:
|
||||
k->imm = k->imm && k2.imm;
|
||||
continue;
|
||||
} else if (cp_opt(cp, '-')) {
|
||||
cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 - k2.u32; goto arith_result;
|
||||
@ -702,25 +718,29 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
|
||||
} else if (cp_opt(cp, '/')) {
|
||||
cp_expr_unary(cp, &k2);
|
||||
if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */
|
||||
if (k2.u32 == 0 ||
|
||||
(k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
|
||||
cp_err(cp, LJ_ERR_BADVAL);
|
||||
if (k->id == CTID_INT32)
|
||||
k->i32 = k->i32 / k2.i32;
|
||||
else
|
||||
k->u32 = k->u32 / k2.u32;
|
||||
continue;
|
||||
if (k->imm && k2.imm) {
|
||||
if (k2.u32 == 0 ||
|
||||
(k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
|
||||
cp_err(cp, LJ_ERR_BADVAL);
|
||||
if (k->id == CTID_INT32)
|
||||
k->i32 = k->i32 / k2.i32;
|
||||
else
|
||||
k->u32 = k->u32 / k2.u32;
|
||||
}
|
||||
goto arith_imm;
|
||||
} else if (cp_opt(cp, '%')) {
|
||||
cp_expr_unary(cp, &k2);
|
||||
if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */
|
||||
if (k2.u32 == 0 ||
|
||||
(k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
|
||||
cp_err(cp, LJ_ERR_BADVAL);
|
||||
if (k->id == CTID_INT32)
|
||||
k->i32 = k->i32 % k2.i32;
|
||||
else
|
||||
k->u32 = k->u32 % k2.u32;
|
||||
continue;
|
||||
if (k->imm && k2.imm) {
|
||||
if (k2.u32 == 0 ||
|
||||
(k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
|
||||
cp_err(cp, LJ_ERR_BADVAL);
|
||||
if (k->id == CTID_INT32)
|
||||
k->i32 = k->i32 % k2.i32;
|
||||
else
|
||||
k->u32 = k->u32 % k2.u32;
|
||||
}
|
||||
goto arith_imm;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
@ -750,7 +770,7 @@ static void cp_expr_kint(CPState *cp, CPValue *k)
|
||||
CType *ct;
|
||||
cp_expr_sub(cp, k, 0);
|
||||
ct = ctype_raw(cp->cts, k->id);
|
||||
if (!ctype_isinteger(ct->info)) cp_err(cp, LJ_ERR_BADVAL);
|
||||
if (!ctype_isinteger(ct->info) || !k->imm) cp_err(cp, LJ_ERR_BADVAL);
|
||||
}
|
||||
|
||||
/* Parse (non-negative) size expression. */
|
||||
@ -1447,6 +1467,7 @@ static CTypeID cp_decl_enum(CPState *cp, CPDecl *sdecl)
|
||||
CTypeID lastid = eid;
|
||||
k.u32 = 0;
|
||||
k.id = CTID_INT32;
|
||||
k.imm = 1;
|
||||
do {
|
||||
GCstr *name = cp->str;
|
||||
if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
|
||||
@ -1610,10 +1631,26 @@ static void cp_decl_array(CPState *cp, CPDecl *decl)
|
||||
CTInfo info = CTINFO(CT_ARRAY, 0);
|
||||
CTSize nelem = CTSIZE_INVALID; /* Default size for a[] or a[?]. */
|
||||
cp_decl_attributes(cp, decl);
|
||||
if (cp_opt(cp, '?'))
|
||||
if (cp_opt(cp, '?')) {
|
||||
info |= CTF_VLA; /* Create variable-length array a[?]. */
|
||||
else if (cp->tok != ']')
|
||||
nelem = cp_expr_ksize(cp);
|
||||
} else if (cp->tok != ']') {
|
||||
CPValue k;
|
||||
CType *ct;
|
||||
cp_expr_sub(cp, &k, 0);
|
||||
ct = ctype_raw(cp->cts, k.id);
|
||||
if (ctype_isinteger(ct->info)) {
|
||||
if (k.imm) {
|
||||
if (k.u32 < 0x80000000u)
|
||||
nelem = k.u32;
|
||||
else
|
||||
cp_err(cp, LJ_ERR_FFI_INVSIZE);
|
||||
} else {
|
||||
info |= CTF_VLA;
|
||||
}
|
||||
} else {
|
||||
cp_err(cp, LJ_ERR_BADVAL);
|
||||
}
|
||||
}
|
||||
cp_check(cp, ']');
|
||||
cp_add(decl, info, nelem);
|
||||
}
|
||||
@ -1623,11 +1660,13 @@ static void cp_decl_func(CPState *cp, CPDecl *fdecl)
|
||||
{
|
||||
CTSize nargs = 0;
|
||||
CTInfo info = CTINFO(CT_FUNC, 0);
|
||||
CTypeID lastid = 0, anchor = 0;
|
||||
CTypeID lastid = 0, anchor = 0, fieldid;
|
||||
uint32_t oldtmask = cp->tmask;
|
||||
cp->tmask |= (1 << CT_FIELD); /* Allow referencing parameters. */
|
||||
if (cp->tok != ')') {
|
||||
do {
|
||||
CPDecl decl;
|
||||
CTypeID ctypeid, fieldid;
|
||||
CTypeID ctypeid;
|
||||
CType *ct;
|
||||
if (cp_opt(cp, '.')) { /* Vararg function. */
|
||||
cp_check(cp, '.'); /* Workaround for the minimalistic lexer. */
|
||||
@ -1658,8 +1697,14 @@ static void cp_decl_func(CPState *cp, CPDecl *fdecl)
|
||||
if (decl.name) ctype_setname(ct, decl.name);
|
||||
ct->info = CTINFO(CT_FIELD, ctypeid);
|
||||
ct->size = nargs++;
|
||||
lj_ctype_addname(cp->cts, ct, fieldid);
|
||||
} while (cp_opt(cp, ','));
|
||||
}
|
||||
/* Parameters went out of scope. */
|
||||
cp->tmask = oldtmask;
|
||||
for (fieldid = anchor; fieldid; fieldid = ctype_get(cp->cts, fieldid)->sib) {
|
||||
lj_ctype_deltype(cp->cts, fieldid);
|
||||
}
|
||||
cp_check(cp, ')');
|
||||
if (cp_opt(cp, '{')) { /* Skip function definition. */
|
||||
int level = 1;
|
||||
@ -1893,6 +1938,7 @@ static void cp_decl_single(CPState *cp)
|
||||
cp_decl_spec(cp, &decl, 0);
|
||||
cp_declarator(cp, &decl);
|
||||
cp->val.id = cp_decl_intern(cp, &decl);
|
||||
cp->val.imm = 0;
|
||||
if (cp->tok != CTOK_EOF) cp_err_token(cp, CTOK_EOF);
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ typedef struct CPValue {
|
||||
uint32_t u32; /* Value for CTID_UINT32. */
|
||||
};
|
||||
CTypeID id; /* C Type ID of the value. */
|
||||
unsigned imm : 1; /* Value is a compile-time constant. */
|
||||
} CPValue;
|
||||
|
||||
/* C parser state. */
|
||||
|
@ -235,6 +235,20 @@ void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id)
|
||||
cts->hash[h] = (CTypeID1)id;
|
||||
}
|
||||
|
||||
/* Remove type element from hash table. */
|
||||
void lj_ctype_deltype(CTState *cts, CTypeID id)
|
||||
{
|
||||
CType *ct = ctype_get(cts, id);
|
||||
uint32_t h = ct_hashname(gcref(ct->name));
|
||||
CTypeID1 *next = &cts->hash[h];
|
||||
while (1) {
|
||||
lj_assertCTS(*next, "ctype not in hash");
|
||||
if (*next == id) break;
|
||||
next = &ctype_get(cts, *next)->next;
|
||||
}
|
||||
*next = ct->next;
|
||||
}
|
||||
|
||||
/* Get a C type by name, matching the type mask. */
|
||||
CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name, uint32_t tmask)
|
||||
{
|
||||
|
@ -461,6 +461,7 @@ static LJ_AINLINE void ctype_setname(CType *ct, GCstr *s)
|
||||
LJ_FUNC CTypeID lj_ctype_new(CTState *cts, CType **ctp);
|
||||
LJ_FUNC CTypeID lj_ctype_intern(CTState *cts, CTInfo info, CTSize size);
|
||||
LJ_FUNC void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id);
|
||||
LJ_FUNC void lj_ctype_deltype(CTState *cts, CTypeID id);
|
||||
LJ_FUNC CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name,
|
||||
uint32_t tmask);
|
||||
LJ_FUNC CType *lj_ctype_getfieldq(CTState *cts, CType *ct, GCstr *name,
|
||||
|
@ -2217,9 +2217,11 @@ LJFOLD(HREF TDUP KNUM)
|
||||
LJFOLDF(fwd_href_tdup)
|
||||
{
|
||||
TValue keyv;
|
||||
cTValue *val;
|
||||
lj_ir_kvalue(J->L, &keyv, fright);
|
||||
if (lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv) == niltvg(J2G(J)) &&
|
||||
lj_opt_fwd_href_nokey(J))
|
||||
val = lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv);
|
||||
/* Check for either nil or the nil value marker in the template table. */
|
||||
if ((tvisnil(val) || tvistab(val)) && lj_opt_fwd_href_nokey(J))
|
||||
return lj_ir_kkptr(J, niltvg(J2G(J)));
|
||||
return NEXTFOLD;
|
||||
}
|
||||
|
@ -233,7 +233,9 @@ static TRef fwd_ahload(jit_State *J, IRRef xref)
|
||||
return lj_ir_knum_u64(J, tv->u64);
|
||||
else if (tvisint(tv))
|
||||
return lj_ir_kint(J, intV(tv));
|
||||
else if (tvisgcv(tv))
|
||||
else if (tvistab(tv)) /* Template table nil value marker. */
|
||||
return TREF_NIL;
|
||||
else if (tvisstr(tv))
|
||||
return lj_ir_kstr(J, strV(tv));
|
||||
}
|
||||
/* Othwerwise: don't intern as a constant. */
|
||||
|
@ -1725,7 +1725,7 @@ static void expr_table(LexState *ls, ExpDesc *e)
|
||||
FuncState *fs = ls->fs;
|
||||
BCLine line = ls->linenumber;
|
||||
GCtab *t = NULL;
|
||||
int vcall = 0, needarr = 0, fixt = 0;
|
||||
int vcall = 0, needarr = 0;
|
||||
uint32_t narr = 1; /* First array index. */
|
||||
uint32_t nhash = 0; /* Number of hash entries. */
|
||||
BCReg freg = fs->freereg;
|
||||
@ -1769,9 +1769,10 @@ static void expr_table(LexState *ls, ExpDesc *e)
|
||||
lj_gc_anybarriert(fs->L, t);
|
||||
if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */
|
||||
expr_kvalue(fs, v, &val);
|
||||
} else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */
|
||||
settabV(fs->L, v, t); /* Preserve key with table itself as value. */
|
||||
fixt = 1; /* Fix this later, after all resizes. */
|
||||
/* Mark nil value with table value itself to preserve the key. */
|
||||
if (key.k == VKSTR && tvisnil(v)) settabV(fs->L, v, t);
|
||||
} else { /* Preserve the key for the following non-const store. */
|
||||
settabV(fs->L, v, t);
|
||||
goto nonconst;
|
||||
}
|
||||
} else {
|
||||
@ -1813,17 +1814,6 @@ static void expr_table(LexState *ls, ExpDesc *e)
|
||||
} else {
|
||||
if (needarr && t->asize < narr)
|
||||
lj_tab_reasize(fs->L, t, narr-1);
|
||||
if (fixt) { /* Fix value for dummy keys in template table. */
|
||||
Node *node = noderef(t->node);
|
||||
uint32_t i, hmask = t->hmask;
|
||||
for (i = 0; i <= hmask; i++) {
|
||||
Node *n = &node[i];
|
||||
if (tvistab(&n->val)) {
|
||||
lj_assertFS(tabV(&n->val) == t, "bad dummy key in template table");
|
||||
setnilV(&n->val); /* Turn value into nil. */
|
||||
}
|
||||
}
|
||||
}
|
||||
lj_gc_check(fs->L);
|
||||
}
|
||||
}
|
||||
|
@ -194,6 +194,7 @@ GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
|
||||
Node *next = nextnode(kn);
|
||||
/* Don't use copyTV here, since it asserts on a copy of a dead key. */
|
||||
n->val = kn->val; n->key = kn->key;
|
||||
if (tvistab(&n->val)) setnilV(&n->val); /* Replace nil value marker. */
|
||||
setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user