aboutsummaryrefslogtreecommitdiff
path: root/lpcode.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-05-29 09:39:03 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-05-29 09:39:03 -0300
commit44fab2a44d06a956c3121ceba2b39ca7b00dc428 (patch)
tree9f492ba2ebaa4fb3cf6554fcb63f3fe026d43a5d /lpcode.c
parent460a35cbcb33fbc56f5a658b96a793b9bb8963e9 (diff)
downloadlpeg-44fab2a44d06a956c3121ceba2b39ca7b00dc428.tar.gz
lpeg-44fab2a44d06a956c3121ceba2b39ca7b00dc428.tar.bz2
lpeg-44fab2a44d06a956c3121ceba2b39ca7b00dc428.zip
Code size stored in code itself
Most patterns do not have code, as they are not directly used for a match; they are created only to compose larger patterns. So, we shouldn't waste space to store the size of their code, as a NULL pointer already indicates that the size is zero.
Diffstat (limited to 'lpcode.c')
-rw-r--r--lpcode.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/lpcode.c b/lpcode.c
index 9d7d0eb..f3b8ae3 100644
--- a/lpcode.c
+++ b/lpcode.c
@@ -392,29 +392,63 @@ static void codegen (CompileState *compst, TTree *tree, int opt, int tt,
392 const Charset *fl); 392 const Charset *fl);
393 393
394 394
395void realloccode (lua_State *L, Pattern *p, int nsize) { 395static void finishrelcode (lua_State *L, Pattern *p, Instruction *block,
396 int size) {
397 if (block == NULL)
398 luaL_error(L, "not enough memory");
399 block->codesize = size;
400 p->code = (Instruction *)block + 1;
401}
402
403
404/*
405** Initialize array 'p->code'
406*/
407static void newcode (lua_State *L, Pattern *p, int size) {
396 void *ud; 408 void *ud;
409 Instruction *block;
397 lua_Alloc f = lua_getallocf(L, &ud); 410 lua_Alloc f = lua_getallocf(L, &ud);
398 void *newblock = f(ud, p->code, p->codesize * sizeof(Instruction), 411 size++; /* slot for 'codesize' */
399 nsize * sizeof(Instruction)); 412 block = (Instruction*) f(ud, NULL, 0, size * sizeof(Instruction));
400 if (newblock == NULL && nsize > 0) 413 finishrelcode(L, p, block, size);
401 luaL_error(L, "not enough memory"); 414}
402 p->code = (Instruction *)newblock; 415
403 p->codesize = nsize; 416
417void freecode (lua_State *L, Pattern *p) {
418 if (p->code != NULL) {
419 void *ud;
420 lua_Alloc f = lua_getallocf(L, &ud);
421 uint osize = p->code[-1].codesize;
422 f(ud, p->code - 1, osize * sizeof(Instruction), 0); /* free block */
423 }
424}
425
426
427/*
428** Assume that 'nsize' is not zero and that 'p->code' already exists.
429*/
430static void realloccode (lua_State *L, Pattern *p, int nsize) {
431 void *ud;
432 lua_Alloc f = lua_getallocf(L, &ud);
433 Instruction *block = p->code - 1;
434 uint osize = block->codesize;
435 nsize++; /* add the 'codesize' slot to size */
436 block = (Instruction*) f(ud, block, osize * sizeof(Instruction),
437 nsize * sizeof(Instruction));
438 finishrelcode(L, p, block, nsize);
404} 439}
405 440
406 441
407/* 442/*
408** Add space for 'n' more instructions and return the index of 443** Add space for an instruction with 'n' slots and return its index.
409** the first one.
410*/ 444*/
411static int nextinstruction (CompileState *compst, int n) { 445static int nextinstruction (CompileState *compst, int n) {
412 int size = compst->p->codesize; 446 int size = compst->p->code[-1].codesize - 1;
413 int ncode = compst->ncode; 447 int ncode = compst->ncode;
414 if (ncode >= size - n) { 448 if (ncode > size - n) {
415 uint nsize = size + (size >> 1) + n; 449 uint nsize = size + (size >> 1) + n;
416 if (nsize > INT_MAX) 450 if (nsize >= INT_MAX)
417 luaL_error(compst->L, "code too large"); 451 luaL_error(compst->L, "pattern code too large");
418 realloccode(compst->L, compst->p, nsize); 452 realloccode(compst->L, compst->p, nsize);
419 } 453 }
420 compst->ncode = ncode + n; 454 compst->ncode = ncode + n;
@@ -998,12 +1032,13 @@ static void peephole (CompileState *compst) {
998 1032
999 1033
1000/* 1034/*
1001** Compile a pattern 1035** Compile a pattern. 'size' is the size of the pattern's tree,
1036** which gives a hint for the size of the final code.
1002*/ 1037*/
1003Instruction *compile (lua_State *L, Pattern *p) { 1038Instruction *compile (lua_State *L, Pattern *p, uint size) {
1004 CompileState compst; 1039 CompileState compst;
1005 compst.p = p; compst.ncode = 0; compst.L = L; 1040 compst.p = p; compst.ncode = 0; compst.L = L;
1006 realloccode(L, p, 4); /* minimum initial size */ 1041 newcode(L, p, size/2u + 2); /* set initial size */
1007 codegen(&compst, p->tree, 0, NOINST, fullset); 1042 codegen(&compst, p->tree, 0, NOINST, fullset);
1008 addinstruction(&compst, IEnd, 0); 1043 addinstruction(&compst, IEnd, 0);
1009 realloccode(L, p, compst.ncode); /* set final size */ 1044 realloccode(L, p, compst.ncode); /* set final size */