aboutsummaryrefslogtreecommitdiff
path: root/lpvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'lpvm.c')
-rw-r--r--lpvm.c47
1 files changed, 18 insertions, 29 deletions
diff --git a/lpvm.c b/lpvm.c
index 1eb7944..0c70766 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -18,11 +18,11 @@
18 18
19/* initial size for call/backtrack stack */ 19/* initial size for call/backtrack stack */
20#if !defined(INITBACK) 20#if !defined(INITBACK)
21#define INITBACK MAXBACK 21#define INITBACK MAXBACK
22#endif 22#endif
23 23
24 24
25#define getoffset(p) (((p) + 1)->offset) 25#define getoffset(p) (((p) + 1)->offset)
26 26
27static const Instruction giveup = {{IGiveup, 0, 0}}; 27static const Instruction giveup = {{IGiveup, 0, 0}};
28 28
@@ -43,7 +43,7 @@ typedef struct Stack {
43} Stack; 43} Stack;
44 44
45 45
46#define getstackbase(L, ptop) ((Stack *)lua_touserdata(L, stackidx(ptop))) 46#define getstackbase(L, ptop) ((Stack *)lua_touserdata(L, stackidx(ptop)))
47 47
48 48
49/* 49/*
@@ -159,7 +159,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
159 const Instruction *p = op; /* current instruction */ 159 const Instruction *p = op; /* current instruction */
160 byte insidepred = OUTPRED; /* labeled failure: label environment is off inside predicates */ 160 byte insidepred = OUTPRED; /* labeled failure: label environment is off inside predicates */
161 stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack->labenv = insidepred; stack++; /* labeled failure */ 161 stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack->labenv = insidepred; stack++; /* labeled failure */
162 *sfail = s; /* labeled failure */ 162 *sfail = s; /* labeled failure */
163 lua_pushlightuserdata(L, stackbase); 163 lua_pushlightuserdata(L, stackbase);
164 for (;;) { 164 for (;;) {
165#if defined(DEBUG) 165#if defined(DEBUG)
@@ -170,7 +170,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
170 printinst(op, p); 170 printinst(op, p);
171#endif 171#endif
172 assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); 172 assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop);
173 assert(insidepred == NOTPRED || insidepred == ANDPRED || insidepred == OUTPRED); 173 assert(insidepred == INPRED || insidepred == OUTPRED);
174 switch ((Opcode)p->i.code) { 174 switch ((Opcode)p->i.code) {
175 case IEnd: { 175 case IEnd: {
176 assert(stack == getstackbase(L, ptop) + 1); 176 assert(stack == getstackbase(L, ptop) + 1);
@@ -191,8 +191,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
191 if (s < e) { p++; s++; } 191 if (s < e) { p++; s++; }
192 else { 192 else {
193 *labelf = LFAIL; /* labeled failure */ 193 *labelf = LFAIL; /* labeled failure */
194 if (insidepred == OUTPRED) 194 updatefarthest(*sfail, s); /*labeled failure */
195 updatefarthest(*sfail, s); /*labeled failure */
196 goto fail; 195 goto fail;
197 } 196 }
198 continue; 197 continue;
@@ -206,8 +205,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
206 if ((byte)*s == p->i.aux && s < e) { p++; s++; } 205 if ((byte)*s == p->i.aux && s < e) { p++; s++; }
207 else { 206 else {
208 *labelf = LFAIL; /* labeled failure */ 207 *labelf = LFAIL; /* labeled failure */
209 if (insidepred == OUTPRED) 208 updatefarthest(*sfail, s); /*labeled failure */
210 updatefarthest(*sfail, s); /*labeled failure */
211 goto fail; 209 goto fail;
212 } 210 }
213 continue; 211 continue;
@@ -223,8 +221,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
223 { p += CHARSETINSTSIZE; s++; } 221 { p += CHARSETINSTSIZE; s++; }
224 else { 222 else {
225 *labelf = LFAIL; /* labeled failure */ 223 *labelf = LFAIL; /* labeled failure */
226 if (insidepred == OUTPRED) 224 updatefarthest(*sfail, s); /*labeled failure */
227 updatefarthest(*sfail, s); /*labeled failure */
228 goto fail; 225 goto fail;
229 } 226 }
230 continue; 227 continue;
@@ -240,8 +237,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
240 int n = p->i.aux; 237 int n = p->i.aux;
241 if (n > s - o) { 238 if (n > s - o) {
242 *labelf = LFAIL; /* labeled failure */ 239 *labelf = LFAIL; /* labeled failure */
243 if (insidepred == OUTPRED) 240 updatefarthest(*sfail, s); /*labeled failure */
244 updatefarthest(*sfail, s); /*labeled failure */
245 goto fail; 241 goto fail;
246 } 242 }
247 s -= n; p++; 243 s -= n; p++;
@@ -280,7 +276,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
280 stack->labenv = insidepred; 276 stack->labenv = insidepred;
281 stack->predchoice = 1; 277 stack->predchoice = 1;
282 stack++; 278 stack++;
283 insidepred = p->i.aux; 279 insidepred = INPRED;
284 p += 2; 280 p += 2;
285 continue; 281 continue;
286 } 282 }
@@ -318,11 +314,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
318 case IThrow: { /* labeled failure */ 314 case IThrow: { /* labeled failure */
319 if (insidepred == OUTPRED) { 315 if (insidepred == OUTPRED) {
320 *labelf = (p+1)->i.key; 316 *labelf = (p+1)->i.key;
321 if (*labelf == LFAIL)
322 luaL_error(L, "labelf is %d", *labelf);
323 stack = getstackbase(L, ptop); 317 stack = getstackbase(L, ptop);
324 stack++; 318 stack++;
325 *sfail = s;
326 } 319 }
327 else { 320 else {
328 while (!(stack-1)->predchoice) { 321 while (!(stack-1)->predchoice) {
@@ -330,21 +323,19 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
330 } 323 }
331 *labelf = LFAIL; 324 *labelf = LFAIL;
332 } 325 }
326 *sfail = s;
333 goto fail; 327 goto fail;
334 } 328 }
335 case IThrowRec: { /* labeled failure */ 329 case IThrowRec: { /* labeled failure */
336 if (insidepred == OUTPRED) { 330 if (insidepred == OUTPRED) {
337 *labelf = (p+2)->i.key; 331 *labelf = (p+2)->i.key;
338 if (*labelf == LFAIL) 332 *sfail = s;
339 luaL_error(L, "labelf is %d", *labelf);
340 *sfail = s;
341 if (stack == stacklimit) 333 if (stack == stacklimit)
342 stack = doublestack(L, &stacklimit, ptop); 334 stack = doublestack(L, &stacklimit, ptop);
343 stack->s = NULL; 335 stack->s = NULL;
344 stack->p = p + 3; 336 stack->p = p + 3;
345 stack->caplevel = captop; 337 stack->caplevel = captop;
346 stack++; 338 stack++;
347 *sfail = s;
348 p += getoffset(p); 339 p += getoffset(p);
349 continue; 340 continue;
350 } else { 341 } else {
@@ -352,6 +343,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
352 --stack; 343 --stack;
353 } 344 }
354 *labelf = LFAIL; 345 *labelf = LFAIL;
346 *sfail = s;
355 } 347 }
356 goto fail; 348 goto fail;
357 } 349 }
@@ -361,8 +353,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
361 /* go through */ 353 /* go through */
362 case IFail: 354 case IFail:
363 *labelf = LFAIL; /* labeled failure */ 355 *labelf = LFAIL; /* labeled failure */
364 if (insidepred == OUTPRED) 356 updatefarthest(*sfail, s); /*labeled failure */
365 updatefarthest(*sfail, s); /*labeled failure */
366 fail: { /* pattern failed: try to backtrack */ 357 fail: { /* pattern failed: try to backtrack */
367 do { /* remove pending calls */ 358 do { /* remove pending calls */
368 assert(stack > getstackbase(L, ptop)); 359 assert(stack > getstackbase(L, ptop));
@@ -371,9 +362,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
371 if (ndyncap > 0) /* is there matchtime captures? */ 362 if (ndyncap > 0) /* is there matchtime captures? */
372 ndyncap -= removedyncap(L, capture, stack->caplevel, captop); 363 ndyncap -= removedyncap(L, capture, stack->caplevel, captop);
373 captop = stack->caplevel; 364 captop = stack->caplevel;
374 assert(((insidepred == ANDPRED || insidepred == NOTPRED) && (stack->labenv == OUTPRED)) || insidepred == stack->labenv 365 assert((insidepred == INPRED && stack->labenv == OUTPRED) || insidepred == stack->labenv);
375 || (insidepred != OUTPRED && stack->labenv != OUTPRED)); 366 insidepred = stack->labenv; /* labeled failure */
376 insidepred = stack->labenv;
377 p = stack->p; 367 p = stack->p;
378#if defined(DEBUG) 368#if defined(DEBUG)
379 printf("**FAIL**\n"); 369 printf("**FAIL**\n");
@@ -391,9 +381,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
391 fr -= rem; /* 'rem' items were popped from Lua stack */ 381 fr -= rem; /* 'rem' items were popped from Lua stack */
392 res = resdyncaptures(L, fr, s - o, e - o); /* get result */ 382 res = resdyncaptures(L, fr, s - o, e - o); /* get result */
393 if (res == -1) { /* fail? */ 383 if (res == -1) { /* fail? */
394 *labelf = LFAIL; /* labeled failure */ 384 *labelf = LFAIL; /* labeled failure */
395 if (insidepred == OUTPRED) 385 updatefarthest(*sfail, s); /*labeled failure */
396 updatefarthest(*sfail, s); /*labeled failure */
397 goto fail; 386 goto fail;
398 } 387 }
399 s = o + res; /* else update current position */ 388 s = o + res; /* else update current position */