RPA Toolkit
work on RVM based regex matching ...
authorMartin Stoilov <martin@rpasearch.com>
Thu, 10 Feb 2011 04:34:21 +0000 (20:34 -0800)
committerMartin Stoilov <martin@rpasearch.com>
Thu, 10 Feb 2011 04:34:21 +0000 (20:34 -0800)
rvm/rvmcpu.c
rvm/rvmcpu.h
tests/regex-test.c

index d284783..3ddfe6f 100644 (file)
@@ -987,6 +987,8 @@ int rvm_asm_dump_reg_to_str(unsigned char reg, char *str, ruint size)
 
        if (reg == XX)
                ret = rvm_snprintf(str, size, "XX ");
+       else if (reg == IP)
+               ret = rvm_snprintf(str, size, "IP ");
        else if (reg == TP)
                ret = rvm_snprintf(str, size, "TP ");
        else if (reg == FP)
@@ -1136,6 +1138,7 @@ static void rvm_cpu_dumpregs(rvm_asmins_t *pi, rvmcpu_t *vm)
                RVM_CPUREG_GETU(vm, 4), RVM_CPUREG_GETU(vm, 5), RVM_CPUREG_GETU(vm, 6), RVM_CPUREG_GETU(vm, 7),
                RVM_CPUREG_GETU(vm, 8), RVM_CPUREG_GETP(vm, TP), (long int)RVM_CPUREG_GETU(vm, FP), (long int)RVM_CPUREG_GETU(vm, SP),
                (long int)RVM_CPUREG_GETU(vm, LR), (long int)RVM_CPUREG_GETU(vm, PC), RVM_CPUREG_GETU(vm, DA),
+               vm->status & RVM_STATUS_E ? 'E' : '_',
                vm->status & RVM_STATUS_V ? 'V' : '_',
                vm->status & RVM_STATUS_C ? 'C' : '_',
                vm->status & RVM_STATUS_N ? 'N' : '_',
index acb9f92..a2e86ea 100644 (file)
@@ -160,6 +160,7 @@ enum {
 #define RVM_STATUS_N (1 << 1)
 #define RVM_STATUS_C (1 << 2)
 #define RVM_STATUS_V (1 << 3)
+#define RVM_STATUS_E (1 << 4)
 #define RVM_STATUS_GETBIT(cpu, bit) ((cpu)->status & (bit))
 #define RVM_STATUS_SETBIT(cpu, bit) do { (cpu)->status |= (bit); } while (0)
 #define RVM_STATUS_CLRBIT(cpu, bit) do { (cpu)->status &= ~(bit); } while (0)
@@ -209,6 +210,7 @@ do { \
 #define R31 31
 
 #define RLST (RVM_REGS_NUM - 1)
+#define IP (RLST - 7)
 #define TP (RLST - 6)
 #define FP (RLST - 5)
 #define SP (RLST - 4)
index 827e8cc..238d13d 100644 (file)
@@ -2,9 +2,12 @@
 #include <stdlib.h>
 #include "rvmcpu.h"
 #include "rmem.h"
+#include "rutf.h"
 
 
 static ruint regextable;
+static int debuginfo = 0;
+static int parseinfo = 0;
 
 #define RPA_MATCHCHR           RVM_OPSWI(RVM_SWI_ID(regextable, 0))
 #define RPA_MATCHCHR_OPT       RVM_OPSWI(RVM_SWI_ID(regextable, 1))
@@ -14,6 +17,7 @@ static ruint regextable;
 #define RPA_MATCHRNG_OPT       RVM_OPSWI(RVM_SWI_ID(regextable, 5))
 #define RPA_MATCHRNG_MUL       RVM_OPSWI(RVM_SWI_ID(regextable, 6))
 #define RPA_MATCHRNG_MOP       RVM_OPSWI(RVM_SWI_ID(regextable, 7))
+#define RPA_SHIFT                      RVM_OPSWI(RVM_SWI_ID(regextable, 8))
 
 
 typedef struct rpainput_s {
@@ -22,6 +26,12 @@ typedef struct rpainput_s {
 } rpainput_t;
 
 
+typedef struct rpainmap_s {
+       const rchar *input;
+       rulong serial;
+} rpainmap_t;
+
+
 typedef struct rpastat_s {
        const rchar *input;
        const rchar *start;
@@ -29,6 +39,8 @@ typedef struct rpastat_s {
        ruint error;
        rpainput_t *instack;
        rulong instacksize;
+       rulong cursize;
+       rpainmap_t ip;
 } rpastat_t;
 
 
@@ -54,12 +66,15 @@ int rpa_stat_init(rpastat_t *stat, const rchar *input, const rchar *start, const
        size = end - start;
        stat->start = start;
        stat->end = end;
-       stat->end = input;
+       stat->input = input;
        stat->error = 0;
-       if (size < stat->instacksize) {
-               stat->instack = r_realloc(stat->instack, size * sizeof(rpainput_t));
-               stat->instacksize = size;
+       stat->cursize = 0;
+       if (stat->instacksize < size) {
+               stat->instack = r_realloc(stat->instack, (size + 1) * sizeof(rpainput_t));
+               stat->instacksize = size + 1;
        }
+       stat->ip.input = input;
+       stat->ip.serial = 0;
        return 0;
 }
 
@@ -83,28 +98,19 @@ static void rpa_matchchr(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rpa_matchchr_opt(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rword res, op2 = RVM_CPUREG_GETU(cpu, R0), op3 = RVM_CPUREG_GETU(cpu, R1);
 
-       res = op2;
-       RVM_CPUREG_SETU(cpu, R0, res);
 }
 
 
 static void rpa_matchchr_mul(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rword res, op2 = RVM_CPUREG_GETU(cpu, R0), op3 = RVM_CPUREG_GETU(cpu, R1);
 
-       res = op2;
-       RVM_CPUREG_SETU(cpu, R0, res);
 }
 
 
 static void rpa_matchchr_mop(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rword res, op2 = RVM_CPUREG_GETU(cpu, R0), op3 = RVM_CPUREG_GETU(cpu, R1);
 
-       res = op2;
-       RVM_CPUREG_SETU(cpu, R0, res);
 }
 
 
@@ -119,31 +125,44 @@ static void rpa_matchrng(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rpa_matchrng_opt(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rword res, op2 = RVM_CPUREG_GETU(cpu, R0), op3 = RVM_CPUREG_GETU(cpu, R1);
 
-       res = op2;
-       RVM_CPUREG_SETU(cpu, R0, res);
 }
 
 
 static void rpa_matchrng_mul(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rword res, op2 = RVM_CPUREG_GETU(cpu, R0), op3 = RVM_CPUREG_GETU(cpu, R1);
 
-       res = op2;
-       RVM_CPUREG_SETU(cpu, R0, res);
 }
 
 
 static void rpa_matchrng_mop(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rword res, op2 = RVM_CPUREG_GETU(cpu, R0), op3 = RVM_CPUREG_GETU(cpu, R1);
 
-       res = op2;
-       RVM_CPUREG_SETU(cpu, R0, res);
+
 }
 
 
+static void rpa_shift(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rpastat_t *stat = (rpastat_t *)cpu->userdata1;
+       rlong tp = RVM_CPUREG_GETL(cpu, TP);
+
+       if (stat->ip.input >= stat->end) {
+               RVM_STATUS_UPDATE(cpu, RVM_STATUS_E, 1);
+               return;
+       }
+
+       tp += 1;
+       if (tp >= (rlong)stat->ip.serial) {
+               rint inc;
+               inc = r_utf8_mbtowc(&stat->instack[tp].wc, (const ruchar*)stat->ip.input, (const ruchar*)stat->end);
+               stat->instack[tp].input = stat->ip.input;
+               stat->ip.input += inc;
+               stat->ip.serial += inc;
+       }
+       RVM_CPUREG_SETL(cpu, IP, stat->instack[tp].wc);
+       RVM_CPUREG_SETL(cpu, TP, tp);
+}
 
 
 static rvm_switable_t switable[] = {
@@ -155,6 +174,7 @@ static rvm_switable_t switable[] = {
                {"RPA_MATCHRNG_OPT", rpa_matchrng_opt},
                {"RPA_MATCHRNG_MUL", rpa_matchrng_mul},
                {"RPA_MATCHRNG_MOP", rpa_matchrng_mop},
+               {"RPA_SHIFT", rpa_shift},
                {NULL, NULL},
 };
 
@@ -164,20 +184,45 @@ int main(int argc, char *argv[])
        rvmcpu_t *cpu;
        rvm_asmins_t code[1024];
        ruint off = 0;
+       rint i;
 
        cpu = rvm_cpu_create_default();
+       cpu->userdata1 = rpa_stat_create();
        regextable = rvm_cpu_addswitable(cpu, switable);
 
-       code[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
-       code[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 2);
-       code[off++] = rvm_asm(RVM_ADD, R2, R0, R1, 0);
-       code[off++] = rvm_asm(RPA_MATCHCHR, DA, XX, XX, 0);
-       code[off++] = rvm_asm(RPA_MATCHCHR, DA, XX, XX, 0);
-       code[off++] = rvm_asm(RVM_EXT, XX, XX, XX, 0);
+       for (i = 1; i < argc; i++) {
+               if (r_strcmp(argv[i], "-L") == 0) {
+               } else if (r_strcmp(argv[i], "-d") == 0) {
+                       debuginfo = 1;
+               } else if (r_strcmp(argv[i], "-p") == 0) {
+                       parseinfo = 1;
+               }
+       }
+
+       for (i = 1; i < argc; i++) {
+               if (r_strcmp(argv[i], "-e") == 0) {
+                       if (++i < argc) {
+                               rstr_t bnfexpr = { argv[i], r_strlen(argv[i]) };
+                               rpa_stat_init((rpastat_t *)cpu->userdata1, bnfexpr.str, bnfexpr.str, bnfexpr.str + bnfexpr.size);
+                       }
+               }
+       }
+
+
+       code[off++] = rvm_asml(RVM_MOV, TP, DA, XX, -1);
+       code[off++] = rvm_asm(RPA_SHIFT, XX, XX, XX, 0);
+       code[off++] = rvm_asm(RPA_SHIFT, XX, XX, XX, 0);
+       code[off++] = rvm_asm(RPA_SHIFT, XX, XX, XX, 0);
+       code[off++] = rvm_asm(RPA_SHIFT, XX, XX, XX, 0);
+       code[off++] = rvm_asm(RPA_SHIFT, XX, XX, XX, 0);
+
        rvm_cpu_exec_debug(cpu, code, 0);
+       rpa_stat_destroy((rpastat_t *)cpu->userdata1);
        rvm_cpu_destroy(cpu);
 
-
-       fprintf(stdout, "It works!\n");
+       if (debuginfo) {
+               r_printf("Max alloc mem: %ld\n", r_debug_get_maxmem());
+               r_printf("Leaked mem: %ld\n", r_debug_get_allocmem());
+       }
        return 0;
 }