diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2022-12-15 16:44:22 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2022-12-15 16:44:22 -0300 |
commit | d70a0c91ad42275af1f6f1b6e37c604442b3f0d1 (patch) | |
tree | 1507250574d5f9b34c32a0fade34fbeaecb7c5f9 /lapi.c | |
parent | 3e6818ca87b8d7aa007e6992295956a92bb89de4 (diff) | |
download | lua-d70a0c91ad42275af1f6f1b6e37c604442b3f0d1.tar.gz lua-d70a0c91ad42275af1f6f1b6e37c604442b3f0d1.tar.bz2 lua-d70a0c91ad42275af1f6f1b6e37c604442b3f0d1.zip |
Dump/undump reuse strings
A repeated string in a dump is represented as an index to its first
occurence, instead of another copy of the string.
Diffstat (limited to 'lapi.c')
-rw-r--r-- | lapi.c | 29 |
1 files changed, 25 insertions, 4 deletions
@@ -1107,16 +1107,37 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, | |||
1107 | } | 1107 | } |
1108 | 1108 | ||
1109 | 1109 | ||
1110 | /* | ||
1111 | ** Dump a function, calling 'writer' to write its parts. Because the | ||
1112 | ** writer can use the stack in unkown ways, this function should not | ||
1113 | ** push things on the stack, but it must anchor an auxiliary table | ||
1114 | ** used by 'luaU_dump'. To do so, it creates the table, anchors the | ||
1115 | ** function that is on the stack in the table, and substitutes the | ||
1116 | ** table for the function in the stack. | ||
1117 | */ | ||
1118 | |||
1110 | LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { | 1119 | LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { |
1111 | int status; | 1120 | int status; |
1121 | StkId fstk; /* pointer to function */ | ||
1112 | TValue *o; | 1122 | TValue *o; |
1113 | lua_lock(L); | 1123 | lua_lock(L); |
1114 | api_checknelems(L, 1); | 1124 | api_checknelems(L, 1); |
1115 | o = s2v(L->top.p - 1); | 1125 | fstk = L->top.p - 1; |
1116 | if (isLfunction(o)) | 1126 | o = s2v(fstk); |
1117 | status = luaU_dump(L, getproto(o), writer, data, strip); | 1127 | if (!isLfunction(o)) |
1118 | else | ||
1119 | status = 1; | 1128 | status = 1; |
1129 | else { | ||
1130 | LClosure *f = clLvalue(o); | ||
1131 | ptrdiff_t fidx = savestack(L, fstk); /* function index */ | ||
1132 | Table *h = luaH_new(L); /* auxiliary table used by 'luaU_dump' */ | ||
1133 | sethvalue2s(L, L->top.p, h); /* anchor it (luaH_set may call GC) */ | ||
1134 | L->top.p++; /* (assume extra slot) */ | ||
1135 | luaH_set(L, h, o, o); /* anchor function into table */ | ||
1136 | setobjs2s(L, fstk, L->top.p - 1); /* move table over function */ | ||
1137 | L->top.p--; /* stack back to initial size */ | ||
1138 | status = luaU_dump(L, f->p, writer, data, strip, h); | ||
1139 | setclLvalue2s(L, restorestack(L, fidx), f); /* put function back */ | ||
1140 | } | ||
1120 | lua_unlock(L); | 1141 | lua_unlock(L); |
1121 | return status; | 1142 | return status; |
1122 | } | 1143 | } |