diff options
author | Mike Pall <mike> | 2012-06-27 22:45:54 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-06-27 22:45:54 +0200 |
commit | 0d1056eeed34cf349938188b177406b6cab91257 (patch) | |
tree | d8fb0c1540db277c98c0d2a9db5118d12e03332e /src | |
parent | ceb76d26b59a03e434e4937ea3ab8447cf949ea0 (diff) | |
download | luajit-0d1056eeed34cf349938188b177406b6cab91257.tar.gz luajit-0d1056eeed34cf349938188b177406b6cab91257.tar.bz2 luajit-0d1056eeed34cf349938188b177406b6cab91257.zip |
Create string hash slots in template tables even for non-const values.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_parse.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c index 2835aef0..7e1d2929 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
@@ -1529,7 +1529,7 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1529 | FuncState *fs = ls->fs; | 1529 | FuncState *fs = ls->fs; |
1530 | BCLine line = ls->linenumber; | 1530 | BCLine line = ls->linenumber; |
1531 | GCtab *t = NULL; | 1531 | GCtab *t = NULL; |
1532 | int vcall = 0, needarr = 0; | 1532 | int vcall = 0, needarr = 0, fixt = 0; |
1533 | int32_t narr = 1; /* First array index. */ | 1533 | int32_t narr = 1; /* First array index. */ |
1534 | uint32_t nhash = 0; /* Number of hash entries. */ | 1534 | uint32_t nhash = 0; /* Number of hash entries. */ |
1535 | BCReg freg = fs->freereg; | 1535 | BCReg freg = fs->freereg; |
@@ -1557,8 +1557,9 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1557 | needarr = vcall = 1; | 1557 | needarr = vcall = 1; |
1558 | } | 1558 | } |
1559 | expr(ls, &val); | 1559 | expr(ls, &val); |
1560 | if (expr_isk_nojump(&val) && expr_isk(&key) && key.k != VKNIL) { | 1560 | if (expr_isk(&key) && key.k != VKNIL && |
1561 | TValue k; | 1561 | (key.k == VKSTR || expr_isk_nojump(&val))) { |
1562 | TValue k, *v; | ||
1562 | if (!t) { /* Create template table on demand. */ | 1563 | if (!t) { /* Create template table on demand. */ |
1563 | BCReg kidx; | 1564 | BCReg kidx; |
1564 | t = lj_tab_new(fs->L, 0, 0); | 1565 | t = lj_tab_new(fs->L, 0, 0); |
@@ -1567,9 +1568,17 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1567 | } | 1568 | } |
1568 | vcall = 0; | 1569 | vcall = 0; |
1569 | expr_kvalue(&k, &key); | 1570 | expr_kvalue(&k, &key); |
1570 | expr_kvalue(lj_tab_set(fs->L, t, &k), &val); | 1571 | v = lj_tab_set(fs->L, t, &k); |
1571 | lj_gc_anybarriert(fs->L, t); | 1572 | lj_gc_anybarriert(fs->L, t); |
1573 | if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ | ||
1574 | expr_kvalue(v, &val); | ||
1575 | } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */ | ||
1576 | settabV(fs->L, v, t); /* Preserve key with table itself as value. */ | ||
1577 | fixt = 1; /* Fix this later, after all resizes. */ | ||
1578 | goto nonconst; | ||
1579 | } | ||
1572 | } else { | 1580 | } else { |
1581 | nonconst: | ||
1573 | if (val.k != VCALL) { expr_toanyreg(fs, &val); vcall = 0; } | 1582 | if (val.k != VCALL) { expr_toanyreg(fs, &val); vcall = 0; } |
1574 | if (expr_isk(&key)) expr_index(fs, e, &key); | 1583 | if (expr_isk(&key)) expr_index(fs, e, &key); |
1575 | bcemit_store(fs, e, &val); | 1584 | bcemit_store(fs, e, &val); |
@@ -1603,6 +1612,16 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1603 | else if (narr < 3) narr = 3; | 1612 | else if (narr < 3) narr = 3; |
1604 | else if (narr > 0x7ff) narr = 0x7ff; | 1613 | else if (narr > 0x7ff) narr = 0x7ff; |
1605 | setbc_d(ip, (uint32_t)narr|(hsize2hbits(nhash)<<11)); | 1614 | setbc_d(ip, (uint32_t)narr|(hsize2hbits(nhash)<<11)); |
1615 | } else if (fixt) { /* Fix value for dummy keys in template table. */ | ||
1616 | Node *node = noderef(t->node); | ||
1617 | uint32_t i, hmask = t->hmask; | ||
1618 | for (i = 0; i <= hmask; i++) { | ||
1619 | Node *n = &node[i]; | ||
1620 | if (tvistab(&n->val)) { | ||
1621 | lua_assert(tabV(&n->val) == t); | ||
1622 | setnilV(&n->val); /* Turn value into nil. */ | ||
1623 | } | ||
1624 | } | ||
1606 | } | 1625 | } |
1607 | } | 1626 | } |
1608 | 1627 | ||