diff options
Diffstat (limited to 'lpvm.c')
-rw-r--r-- | lpvm.c | 52 |
1 files changed, 29 insertions, 23 deletions
@@ -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 */ |