diff options
| -rw-r--r-- | lcode.c | 47 |
1 files changed, 28 insertions, 19 deletions
| @@ -537,6 +537,22 @@ static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { | |||
| 537 | 537 | ||
| 538 | /* | 538 | /* |
| 539 | ** Add constant 'v' to prototype's list of constants (field 'k'). | 539 | ** Add constant 'v' to prototype's list of constants (field 'k'). |
| 540 | */ | ||
| 541 | static int addk (FuncState *fs, Proto *f, TValue *v) { | ||
| 542 | lua_State *L = fs->ls->L; | ||
| 543 | int oldsize = f->sizek; | ||
| 544 | int k = fs->nk; | ||
| 545 | luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); | ||
| 546 | while (oldsize < f->sizek) | ||
| 547 | setnilvalue(&f->k[oldsize++]); | ||
| 548 | setobj(L, &f->k[k], v); | ||
| 549 | fs->nk++; | ||
| 550 | luaC_barrier(L, f, v); | ||
| 551 | return k; | ||
| 552 | } | ||
| 553 | |||
| 554 | |||
| 555 | /* | ||
| 540 | ** Use scanner's table to cache position of constants in constant list | 556 | ** Use scanner's table to cache position of constants in constant list |
| 541 | ** and try to reuse constants. Because some values should not be used | 557 | ** and try to reuse constants. Because some values should not be used |
| 542 | ** as keys (nil cannot be a key, integer keys can collapse with float | 558 | ** as keys (nil cannot be a key, integer keys can collapse with float |
| @@ -544,12 +560,11 @@ static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { | |||
| 544 | ** Note that all functions share the same table, so entering or exiting | 560 | ** Note that all functions share the same table, so entering or exiting |
| 545 | ** a function can make some indices wrong. | 561 | ** a function can make some indices wrong. |
| 546 | */ | 562 | */ |
| 547 | static int addk (FuncState *fs, TValue *key, TValue *v) { | 563 | static int k2proto (FuncState *fs, TValue *key, TValue *v) { |
| 548 | TValue val; | 564 | TValue val; |
| 549 | lua_State *L = fs->ls->L; | ||
| 550 | Proto *f = fs->f; | 565 | Proto *f = fs->f; |
| 551 | int tag = luaH_get(fs->ls->h, key, &val); /* query scanner table */ | 566 | int tag = luaH_get(fs->ls->h, key, &val); /* query scanner table */ |
| 552 | int k, oldsize; | 567 | int k; |
| 553 | if (tag == LUA_VNUMINT) { /* is there an index there? */ | 568 | if (tag == LUA_VNUMINT) { /* is there an index there? */ |
| 554 | k = cast_int(ivalue(&val)); | 569 | k = cast_int(ivalue(&val)); |
| 555 | /* correct value? (warning: must distinguish floats from integers!) */ | 570 | /* correct value? (warning: must distinguish floats from integers!) */ |
| @@ -558,17 +573,11 @@ static int addk (FuncState *fs, TValue *key, TValue *v) { | |||
| 558 | return k; /* reuse index */ | 573 | return k; /* reuse index */ |
| 559 | } | 574 | } |
| 560 | /* constant not found; create a new entry */ | 575 | /* constant not found; create a new entry */ |
| 561 | oldsize = f->sizek; | 576 | k = addk(fs, f, v); |
| 562 | k = fs->nk; | 577 | /* cache for reuse; numerical value does not need GC barrier; |
| 563 | /* numerical value does not need GC barrier; | ||
| 564 | table has no metatable, so it does not need to invalidate cache */ | 578 | table has no metatable, so it does not need to invalidate cache */ |
| 565 | setivalue(&val, k); | 579 | setivalue(&val, k); |
| 566 | luaH_set(L, fs->ls->h, key, &val); | 580 | luaH_set(fs->ls->L, fs->ls->h, key, &val); |
| 567 | luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); | ||
| 568 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); | ||
| 569 | setobj(L, &f->k[k], v); | ||
| 570 | fs->nk++; | ||
| 571 | luaC_barrier(L, f, v); | ||
| 572 | return k; | 581 | return k; |
| 573 | } | 582 | } |
| 574 | 583 | ||
| @@ -579,7 +588,7 @@ static int addk (FuncState *fs, TValue *key, TValue *v) { | |||
| 579 | static int stringK (FuncState *fs, TString *s) { | 588 | static int stringK (FuncState *fs, TString *s) { |
| 580 | TValue o; | 589 | TValue o; |
| 581 | setsvalue(fs->ls->L, &o, s); | 590 | setsvalue(fs->ls->L, &o, s); |
| 582 | return addk(fs, &o, &o); /* use string itself as key */ | 591 | return k2proto(fs, &o, &o); /* use string itself as key */ |
| 583 | } | 592 | } |
| 584 | 593 | ||
| 585 | 594 | ||
| @@ -589,7 +598,7 @@ static int stringK (FuncState *fs, TString *s) { | |||
| 589 | static int luaK_intK (FuncState *fs, lua_Integer n) { | 598 | static int luaK_intK (FuncState *fs, lua_Integer n) { |
| 590 | TValue o; | 599 | TValue o; |
| 591 | setivalue(&o, n); | 600 | setivalue(&o, n); |
| 592 | return addk(fs, &o, &o); /* use integer itself as key */ | 601 | return k2proto(fs, &o, &o); /* use integer itself as key */ |
| 593 | } | 602 | } |
| 594 | 603 | ||
| 595 | /* | 604 | /* |
| @@ -608,7 +617,7 @@ static int luaK_numberK (FuncState *fs, lua_Number r) { | |||
| 608 | lua_Integer ik; | 617 | lua_Integer ik; |
| 609 | setfltvalue(&o, r); | 618 | setfltvalue(&o, r); |
| 610 | if (!luaV_flttointeger(r, &ik, F2Ieq)) /* not an integral value? */ | 619 | if (!luaV_flttointeger(r, &ik, F2Ieq)) /* not an integral value? */ |
| 611 | return addk(fs, &o, &o); /* use number itself as key */ | 620 | return k2proto(fs, &o, &o); /* use number itself as key */ |
| 612 | else { /* must build an alternative key */ | 621 | else { /* must build an alternative key */ |
| 613 | const int nbm = l_floatatt(MANT_DIG); | 622 | const int nbm = l_floatatt(MANT_DIG); |
| 614 | const lua_Number q = l_mathop(ldexp)(l_mathop(1.0), -nbm + 1); | 623 | const lua_Number q = l_mathop(ldexp)(l_mathop(1.0), -nbm + 1); |
| @@ -618,7 +627,7 @@ static int luaK_numberK (FuncState *fs, lua_Number r) { | |||
| 618 | /* result is not an integral value, unless value is too large */ | 627 | /* result is not an integral value, unless value is too large */ |
| 619 | lua_assert(!luaV_flttointeger(k, &ik, F2Ieq) || | 628 | lua_assert(!luaV_flttointeger(k, &ik, F2Ieq) || |
| 620 | l_mathop(fabs)(r) >= l_mathop(1e6)); | 629 | l_mathop(fabs)(r) >= l_mathop(1e6)); |
| 621 | return addk(fs, &kv, &o); | 630 | return k2proto(fs, &kv, &o); |
| 622 | } | 631 | } |
| 623 | } | 632 | } |
| 624 | 633 | ||
| @@ -629,7 +638,7 @@ static int luaK_numberK (FuncState *fs, lua_Number r) { | |||
| 629 | static int boolF (FuncState *fs) { | 638 | static int boolF (FuncState *fs) { |
| 630 | TValue o; | 639 | TValue o; |
| 631 | setbfvalue(&o); | 640 | setbfvalue(&o); |
| 632 | return addk(fs, &o, &o); /* use boolean itself as key */ | 641 | return k2proto(fs, &o, &o); /* use boolean itself as key */ |
| 633 | } | 642 | } |
| 634 | 643 | ||
| 635 | 644 | ||
| @@ -639,7 +648,7 @@ static int boolF (FuncState *fs) { | |||
| 639 | static int boolT (FuncState *fs) { | 648 | static int boolT (FuncState *fs) { |
| 640 | TValue o; | 649 | TValue o; |
| 641 | setbtvalue(&o); | 650 | setbtvalue(&o); |
| 642 | return addk(fs, &o, &o); /* use boolean itself as key */ | 651 | return k2proto(fs, &o, &o); /* use boolean itself as key */ |
| 643 | } | 652 | } |
| 644 | 653 | ||
| 645 | 654 | ||
| @@ -651,7 +660,7 @@ static int nilK (FuncState *fs) { | |||
| 651 | setnilvalue(&v); | 660 | setnilvalue(&v); |
| 652 | /* cannot use nil as key; instead use table itself to represent nil */ | 661 | /* cannot use nil as key; instead use table itself to represent nil */ |
| 653 | sethvalue(fs->ls->L, &k, fs->ls->h); | 662 | sethvalue(fs->ls->L, &k, fs->ls->h); |
| 654 | return addk(fs, &k, &v); | 663 | return k2proto(fs, &k, &v); |
| 655 | } | 664 | } |
| 656 | 665 | ||
| 657 | 666 | ||
