summaryrefslogtreecommitdiff
path: root/libs/liblua/src/lundump.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/liblua/src/lundump.c')
-rw-r--r--libs/liblua/src/lundump.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/libs/liblua/src/lundump.c b/libs/liblua/src/lundump.c
index 4243678a72..5aa55c4457 100644
--- a/libs/liblua/src/lundump.c
+++ b/libs/liblua/src/lundump.c
@@ -120,7 +120,10 @@ static TString *loadStringN (LoadState *S, Proto *p) {
}
else { /* long string */
ts = luaS_createlngstrobj(L, size); /* create string */
+ setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */
+ luaD_inctop(L);
loadVector(S, getstr(ts), size); /* load directly in final place */
+ L->top--; /* pop string */
}
luaC_objbarrier(L, p, ts);
return ts;
@@ -200,13 +203,20 @@ static void loadProtos (LoadState *S, Proto *f) {
}
+/*
+** Load the upvalues for a function. The names must be filled first,
+** because the filling of the other fields can raise read errors and
+** the creation of the error message can call an emergency collection;
+** in that case all prototypes must be consistent for the GC.
+*/
static void loadUpvalues (LoadState *S, Proto *f) {
int i, n;
n = loadInt(S);
f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc);
f->sizeupvalues = n;
- for (i = 0; i < n; i++) {
+ for (i = 0; i < n; i++) /* make array valid for GC */
f->upvalues[i].name = NULL;
+ for (i = 0; i < n; i++) { /* following calls can raise errors */
f->upvalues[i].instack = loadByte(S);
f->upvalues[i].idx = loadByte(S);
f->upvalues[i].kind = loadByte(S);