diff options
Diffstat (limited to 'lpvm.c')
-rw-r--r-- | lpvm.c | 38 |
1 files changed, 23 insertions, 15 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lpvm.c,v 1.6 2015/09/28 17:01:25 roberto Exp $ | 2 | ** $Id: lpvm.c,v 1.9 2016/06/03 20:11:18 roberto Exp $ |
3 | ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) | 3 | ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -33,6 +33,7 @@ static void setlabelfail(Labelset *ls) { | |||
33 | } | 33 | } |
34 | /* labeled failure end */ | 34 | /* labeled failure end */ |
35 | 35 | ||
36 | |||
36 | /* | 37 | /* |
37 | ** {====================================================== | 38 | ** {====================================================== |
38 | ** Virtual Machine | 39 | ** Virtual Machine |
@@ -52,14 +53,16 @@ typedef struct Stack { | |||
52 | 53 | ||
53 | 54 | ||
54 | /* | 55 | /* |
55 | ** Double the size of the array of captures | 56 | ** Make the size of the array of captures 'cap' twice as large as needed |
57 | ** (which is 'captop'). ('n' is the number of new elements.) | ||
56 | */ | 58 | */ |
57 | static Capture *doublecap (lua_State *L, Capture *cap, int captop, int ptop) { | 59 | static Capture *doublecap (lua_State *L, Capture *cap, int captop, |
60 | int n, int ptop) { | ||
58 | Capture *newc; | 61 | Capture *newc; |
59 | if (captop >= INT_MAX/((int)sizeof(Capture) * 2)) | 62 | if (captop >= INT_MAX/((int)sizeof(Capture) * 2)) |
60 | luaL_error(L, "too many captures"); | 63 | luaL_error(L, "too many captures"); |
61 | newc = (Capture *)lua_newuserdata(L, captop * 2 * sizeof(Capture)); | 64 | newc = (Capture *)lua_newuserdata(L, captop * 2 * sizeof(Capture)); |
62 | memcpy(newc, cap, captop * sizeof(Capture)); | 65 | memcpy(newc, cap, (captop - n) * sizeof(Capture)); |
63 | lua_replace(L, caplistidx(ptop)); | 66 | lua_replace(L, caplistidx(ptop)); |
64 | return newc; | 67 | return newc; |
65 | } | 68 | } |
@@ -120,8 +123,8 @@ static int resdyncaptures (lua_State *L, int fr, int curr, int limit) { | |||
120 | */ | 123 | */ |
121 | static void adddyncaptures (const char *s, Capture *base, int n, int fd) { | 124 | static void adddyncaptures (const char *s, Capture *base, int n, int fd) { |
122 | int i; | 125 | int i; |
123 | /* Cgroup capture is already there */ | 126 | base[0].kind = Cgroup; /* create group capture */ |
124 | assert(base[0].kind == Cgroup && base[0].siz == 0); | 127 | base[0].siz = 0; |
125 | base[0].idx = 0; /* make it an anonymous group */ | 128 | base[0].idx = 0; /* make it an anonymous group */ |
126 | for (i = 1; i <= n; i++) { /* add runtime captures */ | 129 | for (i = 1; i <= n; i++) { /* add runtime captures */ |
127 | base[i].kind = Cruntime; | 130 | base[i].kind = Cruntime; |
@@ -148,8 +151,6 @@ static int removedyncap (lua_State *L, Capture *capture, | |||
148 | } | 151 | } |
149 | 152 | ||
150 | 153 | ||
151 | |||
152 | |||
153 | /* | 154 | /* |
154 | ** Opcode interpreter | 155 | ** Opcode interpreter |
155 | */ | 156 | */ |
@@ -170,10 +171,11 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
170 | lua_pushlightuserdata(L, stackbase); | 171 | lua_pushlightuserdata(L, stackbase); |
171 | for (;;) { | 172 | for (;;) { |
172 | #if defined(DEBUG) | 173 | #if defined(DEBUG) |
173 | printinst(op, p); | 174 | printf("-------------------------------------\n"); |
174 | printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ", | ||
175 | s, stack - getstackbase(L, ptop), ndyncap, captop); | ||
176 | printcaplist(capture, capture + captop); | 175 | printcaplist(capture, capture + captop); |
176 | printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ", | ||
177 | s, (int)(stack - getstackbase(L, ptop)), ndyncap, captop); | ||
178 | printinst(op, p); | ||
177 | #endif | 179 | #endif |
178 | assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); | 180 | assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); |
179 | switch ((Opcode)p->i.code) { | 181 | switch ((Opcode)p->i.code) { |
@@ -275,7 +277,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
275 | p += 2; | 277 | p += 2; |
276 | continue; | 278 | continue; |
277 | } | 279 | } |
278 | case IRecov: { /* labeled failure */ | 280 | case IRecov: { /* labeled failure */ |
279 | if (stack == stacklimit) | 281 | if (stack == stacklimit) |
280 | stack = doublestack(L, &stacklimit, ptop); | 282 | stack = doublestack(L, &stacklimit, ptop); |
281 | stack->p = p + getoffset(p); | 283 | stack->p = p + getoffset(p); |
@@ -354,6 +356,9 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
354 | stack++; | 356 | stack++; |
355 | } | 357 | } |
356 | p = pstack->p; | 358 | p = pstack->p; |
359 | #if defined(DEBUG) | ||
360 | printf("**FAIL**\n"); | ||
361 | #endif | ||
357 | continue; | 362 | continue; |
358 | } | 363 | } |
359 | case ICloseRunTime: { | 364 | case ICloseRunTime: { |
@@ -363,6 +368,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
363 | cs.s = o; cs.L = L; cs.ocap = capture; cs.ptop = ptop; | 368 | cs.s = o; cs.L = L; cs.ocap = capture; cs.ptop = ptop; |
364 | n = runtimecap(&cs, capture + captop, s, &rem); /* call function */ | 369 | n = runtimecap(&cs, capture + captop, s, &rem); /* call function */ |
365 | captop -= n; /* remove nested captures */ | 370 | captop -= n; /* remove nested captures */ |
371 | ndyncap -= rem; /* update number of dynamic captures */ | ||
366 | fr -= rem; /* 'rem' items were popped from Lua stack */ | 372 | fr -= rem; /* 'rem' items were popped from Lua stack */ |
367 | res = resdyncaptures(L, fr, s - o, e - o); /* get result */ | 373 | res = resdyncaptures(L, fr, s - o, e - o); /* get result */ |
368 | if (res == -1) { /* fail? */ | 374 | if (res == -1) { /* fail? */ |
@@ -373,10 +379,12 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
373 | } | 379 | } |
374 | s = o + res; /* else update current position */ | 380 | s = o + res; /* else update current position */ |
375 | n = lua_gettop(L) - fr + 1; /* number of new captures */ | 381 | n = lua_gettop(L) - fr + 1; /* number of new captures */ |
376 | ndyncap += n - rem; /* update number of dynamic captures */ | 382 | ndyncap += n; /* update number of dynamic captures */ |
377 | if (n > 0) { /* any new capture? */ | 383 | if (n > 0) { /* any new capture? */ |
384 | if (fr + n >= SHRT_MAX) | ||
385 | luaL_error(L, "too many results in match-time capture"); | ||
378 | if ((captop += n + 2) >= capsize) { | 386 | if ((captop += n + 2) >= capsize) { |
379 | capture = doublecap(L, capture, captop, ptop); | 387 | capture = doublecap(L, capture, captop, n + 2, ptop); |
380 | capsize = 2 * captop; | 388 | capsize = 2 * captop; |
381 | } | 389 | } |
382 | /* add new captures to 'capture' list */ | 390 | /* add new captures to 'capture' list */ |
@@ -413,7 +421,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
413 | capture[captop].idx = p->i.key; | 421 | capture[captop].idx = p->i.key; |
414 | capture[captop].kind = getkind(p); | 422 | capture[captop].kind = getkind(p); |
415 | if (++captop >= capsize) { | 423 | if (++captop >= capsize) { |
416 | capture = doublecap(L, capture, captop, ptop); | 424 | capture = doublecap(L, capture, captop, 0, ptop); |
417 | capsize = 2 * captop; | 425 | capsize = 2 * captop; |
418 | } | 426 | } |
419 | p++; | 427 | p++; |