aboutsummaryrefslogtreecommitdiff
path: root/lpvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'lpvm.c')
-rw-r--r--lpvm.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/lpvm.c b/lpvm.c
index 5234e99..9812e19 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -38,6 +38,7 @@ typedef struct Stack {
38 const char *s; /* saved position (or NULL for calls) */ 38 const char *s; /* saved position (or NULL for calls) */
39 const Instruction *p; /* next instruction */ 39 const Instruction *p; /* next instruction */
40 int caplevel; 40 int caplevel;
41 byte labenv; /* labeled failure */
41} Stack; 42} Stack;
42 43
43 44
@@ -155,7 +156,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
155 int captop = 0; /* point to first empty slot in captures */ 156 int captop = 0; /* point to first empty slot in captures */
156 int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ 157 int ndyncap = 0; /* number of dynamic captures (in Lua stack) */
157 const Instruction *p = op; /* current instruction */ 158 const Instruction *p = op; /* current instruction */
158 stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++; /* labeled failure */ 159 byte labenv = 1; /* labeled failure: label environment is on */
160 stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack->labenv = 1; stack++; /* labeled failure */
159 *sfail = s; /* labeled failure */ 161 *sfail = s; /* labeled failure */
160 lua_pushlightuserdata(L, stackbase); 162 lua_pushlightuserdata(L, stackbase);
161 for (;;) { 163 for (;;) {
@@ -166,7 +168,9 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
166 s, (int)(stack - getstackbase(L, ptop)), ndyncap, captop); 168 s, (int)(stack - getstackbase(L, ptop)), ndyncap, captop);
167 printinst(op, p); 169 printinst(op, p);
168#endif 170#endif
171 printinst(op, p);
169 assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); 172 assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop);
173 assert(labenv == 1);
170 switch ((Opcode)p->i.code) { 174 switch ((Opcode)p->i.code) {
171 case IEnd: { 175 case IEnd: {
172 assert(stack == getstackbase(L, ptop) + 1); 176 assert(stack == getstackbase(L, ptop) + 1);
@@ -257,6 +261,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
257 stack->p = p + getoffset(p); 261 stack->p = p + getoffset(p);
258 stack->s = s; 262 stack->s = s;
259 stack->caplevel = captop; 263 stack->caplevel = captop;
264 stack->labenv = labenv; /* labeled failure */
260 stack++; 265 stack++;
261 p += 2; 266 p += 2;
262 continue; 267 continue;
@@ -287,6 +292,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
287 case IBackCommit: { 292 case IBackCommit: {
288 assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); 293 assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL);
289 s = (--stack)->s; 294 s = (--stack)->s;
295 labenv = stack->labenv; /* labeled failure */
296 assert(labenv == 1); /* labeled failure */
290 captop = stack->caplevel; 297 captop = stack->caplevel;
291 p += getoffset(p); 298 p += getoffset(p);
292 continue; 299 continue;
@@ -296,12 +303,18 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
296 lua_rawgeti(L, ktableidx(ptop), (p+1)->i.key); 303 lua_rawgeti(L, ktableidx(ptop), (p+1)->i.key);
297 printf("IThrow there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L)); 304 printf("IThrow there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L));
298 lua_pop(L, 1);*/ 305 lua_pop(L, 1);*/
299 *labelf = (p+1)->i.key; 306 if (labenv) {
300 if (*labelf == LFAIL) 307 *labelf = (p+1)->i.key;
308 if (*labelf == LFAIL)
301 luaL_error(L, "labelf is %d", *labelf); 309 luaL_error(L, "labelf is %d", *labelf);
302 *sfail = s; 310 stack = getstackbase(L, ptop);
303 stack = getstackbase(L, ptop); 311 stack++;
304 stack++; 312 printf("IThrow stack->labenv = %d\n", stack->labenv);
313 }
314 else {
315 labelf = LFAIL;
316 }
317 *sfail = s;
305 goto fail; 318 goto fail;
306 } 319 }
307 case IThrowRec: { /* labeled failure */ 320 case IThrowRec: { /* labeled failure */
@@ -309,18 +322,25 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
309 lua_rawgeti(L, ktableidx(ptop), (p+2)->i.key); 322 lua_rawgeti(L, ktableidx(ptop), (p+2)->i.key);
310 printf("IThrowRec there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L)); 323 printf("IThrowRec there %s top = %d\n", lua_tostring(L, -1), lua_gettop(L));
311 lua_pop(L, 1);*/ 324 lua_pop(L, 1);*/
312 *labelf = (p+2)->i.key; 325 printf("labenv here = %d\n", labenv);
313 if (*labelf == LFAIL) 326 if (labenv) {
314 luaL_error(L, "labelf is %d", *labelf); 327 *labelf = (p+2)->i.key;
315 *sfail = s; 328 if (*labelf == LFAIL)
316 if (stack == stacklimit) 329 luaL_error(L, "labelf is %d", *labelf);
317 stack = doublestack(L, &stacklimit, ptop); 330 *sfail = s;
318 stack->s = NULL; 331 if (stack == stacklimit)
319 stack->p = p + 3; 332 stack = doublestack(L, &stacklimit, ptop);
320 stack->caplevel = captop; 333 stack->s = NULL;
321 stack++; 334 stack->p = p + 3;
322 p += getoffset(p); 335 stack->caplevel = captop;
323 continue; 336 stack++;
337 p += getoffset(p);
338 continue;
339 } else {
340 labelf = LFAIL;
341 }
342 *sfail = s;
343 goto fail;
324 } 344 }
325 case IFailTwice: 345 case IFailTwice:
326 assert(stack > getstackbase(L, ptop)); 346 assert(stack > getstackbase(L, ptop));
@@ -337,6 +357,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
337 if (ndyncap > 0) /* is there matchtime captures? */ 357 if (ndyncap > 0) /* is there matchtime captures? */
338 ndyncap -= removedyncap(L, capture, stack->caplevel, captop); 358 ndyncap -= removedyncap(L, capture, stack->caplevel, captop);
339 captop = stack->caplevel; 359 captop = stack->caplevel;
360 labenv = stack->labenv;
361 assert(labenv == 1);
340 p = stack->p; 362 p = stack->p;
341#if defined(DEBUG) 363#if defined(DEBUG)
342 printf("**FAIL**\n"); 364 printf("**FAIL**\n");