diff options
Diffstat (limited to 'lpvm.c')
-rw-r--r-- | lpvm.c | 47 |
1 files changed, 18 insertions, 29 deletions
@@ -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 | ||
27 | static const Instruction giveup = {{IGiveup, 0, 0}}; | 27 | static 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 */ |