** Use scanner's table to cache position of constants in constant list ** and try to reuse constants. Because some values should not be used ** as keys (nil cannot be a key, integer keys can collapse with float ** keys), the caller must provide a useful 'key' for indexing the cache. */
| 563 | ** keys), the caller must provide a useful 'key' for indexing the cache. |
| 564 | */ |
| 565 | static int k2proto (FuncState *fs, TValue *key, TValue *v) { |
| 566 | TValue val; |
| 567 | Proto *f = fs->f; |
| 568 | int tag = luaH_get(fs->kcache, key, &val); /* query scanner table */ |
| 569 | if (!tagisempty(tag)) { /* is there an index there? */ |
| 570 | int k = cast_int(ivalue(&val)); |
| 571 | /* collisions can happen only for float keys */ |
| 572 | lua_assert(ttisfloat(key) || luaV_rawequalobj(&f->k[k], v)); |
| 573 | return k; /* reuse index */ |
| 574 | } |
| 575 | else { /* constant not found; create a new entry */ |
| 576 | int k = addk(fs, f, v); |
| 577 | /* cache it for reuse; numerical value does not need GC barrier; |
| 578 | table is not a metatable, so it does not need to invalidate cache */ |
| 579 | setivalue(&val, k); |
| 580 | luaH_set(fs->ls->L, fs->kcache, key, &val); |
| 581 | return k; |
| 582 | } |
| 583 | } |
| 584 | |
| 585 | |
| 586 | /* |