aboutsummaryrefslogtreecommitdiff
path: root/lpvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'lpvm.c')
-rw-r--r--lpvm.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/lpvm.c b/lpvm.c
index 277acf7..a934478 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -162,15 +162,16 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
162 int captop = 0; /* point to first empty slot in captures */ 162 int captop = 0; /* point to first empty slot in captures */
163 int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ 163 int ndyncap = 0; /* number of dynamic captures (in Lua stack) */
164 const Instruction *p = op; /* current instruction */ 164 const Instruction *p = op; /* current instruction */
165 const Instruction *pk = NULL; /* resume instruction */
165 Labelset lsfail; 166 Labelset lsfail;
166 setlabelfail(&lsfail); 167 setlabelfail(&lsfail);
167 stack->p = &giveup; stack->s = s; stack->ls = &lsfail; stack->caplevel = 0; stack++; /* labeled failure */ 168 stack->p = &giveup; stack->s = s; stack->ls = &lsfail; stack->caplevel = 0; stack++; /* labeled failure */
168 lua_pushlightuserdata(L, stackbase); 169 lua_pushlightuserdata(L, stackbase);
169 for (;;) { 170 for (;;) {
170#if defined(DEBUG) 171#if defined(DEBUG)
172 printinst(op, p);
171 printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ", 173 printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ",
172 s, stack - getstackbase(L, ptop), ndyncap, captop); 174 s, stack - getstackbase(L, ptop), ndyncap, captop);
173 printinst(op, p);
174 printcaplist(capture, capture + captop); 175 printcaplist(capture, capture + captop);
175#endif 176#endif
176 assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); 177 assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop);
@@ -194,6 +195,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
194 if (s < e) { p++; s++; } 195 if (s < e) { p++; s++; }
195 else { 196 else {
196 *labelf = LFAIL; /* labeled failure */ 197 *labelf = LFAIL; /* labeled failure */
198 pk = p + 1;
197 *sfail = s; 199 *sfail = s;
198 goto fail; 200 goto fail;
199 } 201 }
@@ -208,6 +210,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
208 if ((byte)*s == p->i.aux && s < e) { p++; s++; } 210 if ((byte)*s == p->i.aux && s < e) { p++; s++; }
209 else { 211 else {
210 *labelf = LFAIL; /* labeled failure */ 212 *labelf = LFAIL; /* labeled failure */
213 pk = p + 1;
211 *sfail = s; 214 *sfail = s;
212 goto fail; 215 goto fail;
213 } 216 }
@@ -224,6 +227,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
224 { p += CHARSETINSTSIZE; s++; } 227 { p += CHARSETINSTSIZE; s++; }
225 else { 228 else {
226 *labelf = LFAIL; /* labeled failure */ 229 *labelf = LFAIL; /* labeled failure */
230 pk = p + CHARSETINSTSIZE;
227 *sfail = s; 231 *sfail = s;
228 goto fail; 232 goto fail;
229 } 233 }
@@ -240,6 +244,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
240 int n = p->i.aux; 244 int n = p->i.aux;
241 if (n > s - o) { 245 if (n > s - o) {
242 *labelf = LFAIL; /* labeled failure */ 246 *labelf = LFAIL; /* labeled failure */
247 pk = p + 1;
243 *sfail = s; 248 *sfail = s;
244 goto fail; 249 goto fail;
245 } 250 }
@@ -269,17 +274,6 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
269 p += 2; 274 p += 2;
270 continue; 275 continue;
271 } 276 }
272 case ILabChoice: { /* labeled failure */
273 if (stack == stacklimit)
274 stack = doublestack(L, &stacklimit, ptop);
275 stack->p = p + getoffset(p);
276 stack->s = s;
277 stack->ls = (const Labelset *) ((p + 2)->buff);
278 stack->caplevel = captop;
279 stack++;
280 p += (CHARSETINSTSIZE - 1) + 2;
281 continue;
282 }
283 case IRecov: { /* labeled failure */ 277 case IRecov: { /* labeled failure */
284 if (stack == stacklimit) 278 if (stack == stacklimit)
285 stack = doublestack(L, &stacklimit, ptop); 279 stack = doublestack(L, &stacklimit, ptop);
@@ -291,7 +285,6 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
291 p += (CHARSETINSTSIZE - 1) + 2; 285 p += (CHARSETINSTSIZE - 1) + 2;
292 continue; 286 continue;
293 } 287 }
294
295 case ICall: { 288 case ICall: {
296 if (stack == stacklimit) 289 if (stack == stacklimit)
297 stack = doublestack(L, &stacklimit, ptop); 290 stack = doublestack(L, &stacklimit, ptop);
@@ -304,7 +297,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
304 } 297 }
305 case ICommit: { 298 case ICommit: {
306 assert(stack > getstackbase(L, ptop) && (stack - 1)->ls != NULL); /* labeled failure */ 299 assert(stack > getstackbase(L, ptop) && (stack - 1)->ls != NULL); /* labeled failure */
307 /* assert((stack - 1)->s != NULL); labeled failure: IRecov does not push s onto the stack */ 300 /*assert((stack - 1)->s != NULL); labeled failure: IRecov does not push s onto the stack */
308 stack--; 301 stack--;
309 p += getoffset(p); 302 p += getoffset(p);
310 continue; 303 continue;
@@ -325,6 +318,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
325 } 318 }
326 case IThrow: { /* labeled failure */ 319 case IThrow: { /* labeled failure */
327 *labelf = p->i.aux; 320 *labelf = p->i.aux;
321 pk = p + 1;
328 *sfail = s; 322 *sfail = s;
329 goto fail; 323 goto fail;
330 } 324 }
@@ -334,20 +328,31 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
334 /* go through */ 328 /* go through */
335 case IFail: 329 case IFail:
336 *labelf = LFAIL; /* labeled failure */ 330 *labelf = LFAIL; /* labeled failure */
331 pk = NULL;
337 *sfail = s; 332 *sfail = s;
338 fail: { /* pattern failed: try to backtrack */ 333 fail: { /* pattern failed: try to backtrack */
339 const Labelset *auxlab = NULL; 334 const Labelset *auxlab = NULL;
335 Stack *pstack = stack;
340 do { /* remove pending calls */ 336 do { /* remove pending calls */
341 assert(stack > getstackbase(L, ptop)); 337 assert(pstack > getstackbase(L, ptop));
342 auxlab = (--stack)->ls; 338 auxlab = (--pstack)->ls;
343 } while (auxlab == NULL || (stack->p != &giveup && !testlabel(stack->ls->cs, *labelf))); 339 } while (auxlab == NULL || !(pstack->p == &giveup || testlabel(pstack->ls->cs, *labelf)));
344 if (stack->p == &giveup || stack->s != NULL) { /* labeled failure */ 340 if (pstack->s != NULL) { /* labeled failure: giveup or backtrack frame */
341 stack = pstack;
345 s = stack->s; 342 s = stack->s;
343 if (ndyncap > 0) /* is there matchtime captures? */
344 ndyncap -= removedyncap(L, capture, stack->caplevel, captop);
345 captop = stack->caplevel;
346 } else { /* labeled failure: recovery frame */
347 if (stack == stacklimit)
348 stack = doublestack(L, &stacklimit, ptop);
349 stack->s = NULL;
350 stack->p = pk; /* save return address */
351 stack->ls = NULL;
352 stack->caplevel = captop; /* TODO: really necessary?? */
353 stack++;
346 } 354 }
347 if (ndyncap > 0) /* is there matchtime captures? */ 355 p = pstack->p;
348 ndyncap -= removedyncap(L, capture, stack->caplevel, captop);
349 captop = stack->caplevel;
350 p = stack->p;
351 continue; 356 continue;
352 } 357 }
353 case ICloseRunTime: { 358 case ICloseRunTime: {
@@ -361,7 +366,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
361 res = resdyncaptures(L, fr, s - o, e - o); /* get result */ 366 res = resdyncaptures(L, fr, s - o, e - o); /* get result */
362 if (res == -1) { /* fail? */ 367 if (res == -1) { /* fail? */
363 *labelf = LFAIL; /* labeled failure */ 368 *labelf = LFAIL; /* labeled failure */
364 *sfail = (const char *) s; /* TODO: ??? */ 369 *sfail = (const char *) s;
370 pk = NULL;
365 goto fail; 371 goto fail;
366 } 372 }
367 s = o + res; /* else update current position */ 373 s = o + res; /* else update current position */