aboutsummaryrefslogtreecommitdiff
path: root/lpvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'lpvm.c')
-rw-r--r--lpvm.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/lpvm.c b/lpvm.c
index c256083..911b4c5 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -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*/
57static Capture *doublecap (lua_State *L, Capture *cap, int captop, int ptop) { 59static 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*/
121static void adddyncaptures (const char *s, Capture *base, int n, int fd) { 124static 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++;