| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: lvm.c,v 1.15 2023/04/16 20:46:17 nikita Exp $ */ | | 1 | /* $NetBSD: lvm.c,v 1.16 2023/04/17 19:35:36 nikita Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | ** Id: lvm.c | | 4 | ** Id: lvm.c |
5 | ** Lua virtual machine | | 5 | ** Lua virtual machine |
6 | ** See Copyright Notice in lua.h | | 6 | ** See Copyright Notice in lua.h |
7 | */ | | 7 | */ |
8 | | | 8 | |
9 | #define lvm_c | | 9 | #define lvm_c |
10 | #define LUA_CORE | | 10 | #define LUA_CORE |
11 | | | 11 | |
12 | #include "lprefix.h" | | 12 | #include "lprefix.h" |
13 | | | 13 | |
14 | #ifndef _KERNEL | | 14 | #ifndef _KERNEL |
| @@ -688,43 +688,45 @@ void luaV_concat (lua_State *L, int tota | | | @@ -688,43 +688,45 @@ void luaV_concat (lua_State *L, int tota |
688 | luaT_tryconcatTM(L); | | 688 | luaT_tryconcatTM(L); |
689 | else if (isemptystr(s2v(top - 1))) /* second operand is empty? */ | | 689 | else if (isemptystr(s2v(top - 1))) /* second operand is empty? */ |
690 | cast_void(tostring(L, s2v(top - 2))); /* result is first operand */ | | 690 | cast_void(tostring(L, s2v(top - 2))); /* result is first operand */ |
691 | else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */ | | 691 | else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */ |
692 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ | | 692 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ |
693 | } | | 693 | } |
694 | else { | | 694 | else { |
695 | /* at least two non-empty string values; get as many as possible */ | | 695 | /* at least two non-empty string values; get as many as possible */ |
696 | size_t tl = vslen(s2v(top - 1)); | | 696 | size_t tl = vslen(s2v(top - 1)); |
697 | TString *ts; | | 697 | TString *ts; |
698 | /* collect total length and number of strings */ | | 698 | /* collect total length and number of strings */ |
699 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { | | 699 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { |
700 | size_t l = vslen(s2v(top - n - 1)); | | 700 | size_t l = vslen(s2v(top - n - 1)); |
701 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) | | 701 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { |
| | | 702 | L->top = top - total; /* pop strings to avoid wasting stack */ |
702 | luaG_runerror(L, "string length overflow"); | | 703 | luaG_runerror(L, "string length overflow"); |
| | | 704 | } |
703 | tl += l; | | 705 | tl += l; |
704 | } | | 706 | } |
705 | if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ | | 707 | if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ |
706 | char buff[LUAI_MAXSHORTLEN]; | | 708 | char buff[LUAI_MAXSHORTLEN]; |
707 | copy2buff(top, n, buff); /* copy strings to buffer */ | | 709 | copy2buff(top, n, buff); /* copy strings to buffer */ |
708 | ts = luaS_newlstr(L, buff, tl); | | 710 | ts = luaS_newlstr(L, buff, tl); |
709 | } | | 711 | } |
710 | else { /* long string; copy strings directly to final result */ | | 712 | else { /* long string; copy strings directly to final result */ |
711 | ts = luaS_createlngstrobj(L, tl); | | 713 | ts = luaS_createlngstrobj(L, tl); |
712 | copy2buff(top, n, getstr(ts)); | | 714 | copy2buff(top, n, getstr(ts)); |
713 | } | | 715 | } |
714 | setsvalue2s(L, top - n, ts); /* create result */ | | 716 | setsvalue2s(L, top - n, ts); /* create result */ |
715 | } | | 717 | } |
716 | total -= n-1; /* got 'n' strings to create 1 new */ | | 718 | total -= n-1; /* got 'n' strings to create 1 new */ |
717 | L->top -= n-1; /* popped 'n' strings and pushed one */ | | 719 | L->top = top - (n - 1); /* popped 'n' strings and pushed one */ |
718 | } while (total > 1); /* repeat until only 1 result left */ | | 720 | } while (total > 1); /* repeat until only 1 result left */ |
719 | } | | 721 | } |
720 | | | 722 | |
721 | | | 723 | |
722 | /* | | 724 | /* |
723 | ** Main operation 'ra = #rb'. | | 725 | ** Main operation 'ra = #rb'. |
724 | */ | | 726 | */ |
725 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { | | 727 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { |
726 | const TValue *tm; | | 728 | const TValue *tm; |
727 | switch (ttypetag(rb)) { | | 729 | switch (ttypetag(rb)) { |
728 | case LUA_VTABLE: { | | 730 | case LUA_VTABLE: { |
729 | Table *h = hvalue(rb); | | 731 | Table *h = hvalue(rb); |
730 | tm = fasttm(L, h->metatable, TM_LEN); | | 732 | tm = fasttm(L, h->metatable, TM_LEN); |