RPA Toolkit
added data section to codegen
authorMartin Stoilov <martin@rpasearch.com>
Thu, 17 Feb 2011 06:53:20 +0000 (22:53 -0800)
committerMartin Stoilov <martin@rpasearch.com>
Thu, 17 Feb 2011 06:53:20 +0000 (22:53 -0800)
17 files changed:
arch/linux/x86_64/rtypes.h
rlib/rarray.c
rlib/rarray.h
rlib/rstring.c
rvm/rvmcodegen.c
rvm/rvmcodegen.h
rvm/rvmcodemap.c
rvm/rvmcodemap.h
rvm/rvmcpu.c
rvm/rvmreg.h
rvm/rvmrelocmap.c
tests/asm-bl.c
tests/codegen-test.c
tests/codemap-test.c
tests/funcarg-test.c
tests/regex-test.c
tests/string-test.c

index 03df991..1f3dedc 100644 (file)
@@ -31,6 +31,7 @@ typedef unsigned long rulong;
 typedef unsigned int ruint;
 typedef unsigned short rushort;
 typedef unsigned char ruchar;
+typedef ruchar rbyte;
 typedef double rdouble;
 typedef float rfloat;
 typedef rint rboolean;
@@ -65,6 +66,7 @@ typedef struct {ruint32 p1; ruint32 p2;} rpair_t;
 
 #define R_DEBUG_BRAKE __asm__ ("int $3")
 #define ASSERT(__a__) do {if (!(__a__)) R_DEBUG_BRAKE; } while (0)
+#define R_SIZE_ALIGN(s, n) ((((s) + (n) - 1) / (n)) * (n))
 
 #ifndef NULL
 #ifdef __cplusplus
index ca880f1..7cb04f7 100644 (file)
@@ -110,10 +110,17 @@ rint r_array_replace(rarray_t *array, ruint index, rconstpointer data)
 }
 
 
-void r_array_setlength(rarray_t *array, ruint len)
+rint r_array_setlength(rarray_t *array, ruint len)
 {
        r_array_checkexpand(array, len);
-       array->len = len;
+       r_array_length(array) = len;
+       return r_array_length(array);
+}
+
+
+rint r_array_expand(rarray_t *array, ruint len)
+{
+       return r_array_setlength(array, r_array_length(array) + len);
 }
 
 
index efa0f75..4f706c6 100644 (file)
@@ -43,7 +43,8 @@ rint r_array_add(rarray_t *array, rconstpointer data);
 rint r_array_removelast(rarray_t *array);
 rint r_array_insert(rarray_t *array, ruint index, rconstpointer data);
 rint r_array_replace(rarray_t *array, ruint index, rconstpointer data);
-void r_array_setlength(rarray_t *array, ruint len);
+rint r_array_setlength(rarray_t *array, ruint len);
+rint r_array_expand(rarray_t *array, ruint len);
 void *r_array_slot_expand(rarray_t *array, ruint index);
 
 /*
index 90a9868..9b9e336 100644 (file)
@@ -30,7 +30,7 @@ rboolean r_stringncmp(const rchar *str, const rchar *s2, rsize_t n)
 
 rsize_t r_strlen(const rchar *s)
 {
-       return strlen(s);
+       return s ? strlen(s) : 0;
 }
 
 
index f730d34..bce0afe 100644 (file)
@@ -12,6 +12,7 @@ rvm_codegen_t *rvm_codegen_create()
                return (NULL);
        r_memset(cg, 0, sizeof(*cg));
        cg->code = r_array_create(sizeof(rvm_asmins_t));
+       cg->data = r_array_create(sizeof(rbyte));
        cg->codemap = rvm_codemap_create();
        cg->relocmap = rvm_relocmap_create();
        return cg;
@@ -22,6 +23,7 @@ void rvm_codegen_destroy(rvm_codegen_t *cg)
 {
        rvm_codemap_destroy(cg->codemap);
        rvm_relocmap_destroy(cg->relocmap);
+       r_object_destroy((robject_t*)cg->data);
        r_object_destroy((robject_t*)cg->code);
        r_free(cg);
 }
@@ -82,13 +84,19 @@ ruint rvm_codegen_addlabelins_s(rvm_codegen_t *cg, const rchar* name, rvm_asmins
 }
 
 
-ruint rvm_codegen_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, ruint namesize, rvm_asmins_t ins)
+ruint rvm_codegen_index_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, rulong index, rvm_asmins_t ins)
 {
-       rvm_relocmap_add(cg->relocmap, type, rvm_codegen_getcodesize(cg), rvm_codemap_lookup(cg->codemap, name, namesize));
+       rvm_relocmap_add(cg->relocmap, type, rvm_codegen_getcodesize(cg), index);
        return rvm_codegen_addins(cg, ins);
 }
 
 
+ruint rvm_codegen_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, ruint namesize, rvm_asmins_t ins)
+{
+       return rvm_codegen_index_addrelocins(cg, type, rvm_codemap_lookup(cg->codemap, name, namesize), ins);
+}
+
+
 ruint rvm_codegen_addrelocins_s(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, rvm_asmins_t ins)
 {
        return rvm_codegen_addrelocins(cg, type, name, r_strlen(name), ins);
@@ -98,6 +106,7 @@ ruint rvm_codegen_addrelocins_s(rvm_codegen_t *cg, rvm_reloctype_t type, const r
 rint rvm_codegen_relocate(rvm_codegen_t *cg, rvm_codelabel_t **err)
 {
        rvm_codemap_addpointer_s(cg->codemap, ".code", r_array_slot(cg->code, 0));
+       rvm_codemap_addpointer_s(cg->codemap, ".data", r_array_slot(cg->data, 0));
        return rvm_relocmap_relocate(cg->relocmap, cg->codemap, (rvm_asmins_t *)r_array_slot(cg->code, 0), err);
 }
 
@@ -157,3 +166,33 @@ void rvm_codegen_funcend(rvm_codegen_t *cg)
        rvm_codegen_addins(cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
        rvm_codegen_addins(cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
 }
+
+rlong rvm_codegen_adddata(rvm_codegen_t *cg, const rchar *name, ruint namesize, rconstpointer data, rsize_t size)
+{
+       rpointer buffer;
+       rulong cursize = R_SIZE_ALIGN(r_array_length(cg->data), sizeof(rword));
+
+       r_array_setlength(cg->data, cursize + size + sizeof(rword));
+       buffer = r_array_slot(cg->data, cursize);
+       r_memset(buffer, 0, size + sizeof(rword));
+       r_memmove(buffer, data, size);
+       return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".data"), cursize);
+}
+
+
+rlong rvm_codegen_adddata_s(rvm_codegen_t *cg, const rchar *name, rconstpointer data, rsize_t size)
+{
+       return rvm_codegen_adddata(cg, name, r_strlen(name), data, size);
+}
+
+
+rlong rvm_codegen_addstring(rvm_codegen_t *cg, const rchar *name, ruint namesize, const rchar* data)
+{
+       return rvm_codegen_adddata(cg, name, namesize, data, r_strlen(data) + 1);
+}
+
+
+rlong rvm_codegen_addstring_s(rvm_codegen_t *cg, const rchar *name, const rchar* data)
+{
+       return rvm_codegen_addstring(cg, name, r_strlen(name), data);
+}
index a66cf41..2cff991 100644 (file)
@@ -18,6 +18,7 @@ extern "C" {
 
 typedef struct rvm_codegen_s {
        rarray_t *code;
+       rarray_t *data;
        ruint codeoff;
        rvm_codemap_t *codemap;
        rvm_relocmap_t *relocmap;
@@ -34,6 +35,7 @@ void rvm_codegen_funcend(rvm_codegen_t *cg);
 ruint rvm_codegen_addins(rvm_codegen_t *cg, rvm_asmins_t ins);
 ruint rvm_codegen_addlabelins(rvm_codegen_t *cg, const rchar* name, ruint namesize, rvm_asmins_t ins);
 ruint rvm_codegen_addlabelins_s(rvm_codegen_t *cg, const rchar* name, rvm_asmins_t ins);
+ruint rvm_codegen_index_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, rulong index, rvm_asmins_t ins);
 ruint rvm_codegen_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, ruint namesize, rvm_asmins_t ins);
 ruint rvm_codegen_addrelocins_s(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, rvm_asmins_t ins);
 ruint rvm_codegen_insertins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins);
@@ -45,6 +47,10 @@ void rvm_codegen_clear(rvm_codegen_t *cg);
 rint rvm_codegen_relocate(rvm_codegen_t *cg, rvm_codelabel_t **err);
 rlong rvm_codegen_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize);
 rlong rvm_codegen_addlabel_s(rvm_codegen_t *cg, const rchar* name);
+rlong rvm_codegen_adddata(rvm_codegen_t *cg, const rchar *name, ruint namesize, rconstpointer data, rsize_t size);
+rlong rvm_codegen_adddata_s(rvm_codegen_t *cg, const rchar *name, rconstpointer data, rsize_t size);
+rlong rvm_codegen_addstring(rvm_codegen_t *cg, const rchar *name, ruint namesize, const rchar* data);
+rlong rvm_codegen_addstring_s(rvm_codegen_t *cg, const rchar *name, const rchar* data);
 
 #ifdef __cplusplus
 }
index 43624d7..ee7cc3b 100644 (file)
@@ -25,7 +25,7 @@ void rvm_codemap_destroy(rvm_codemap_t *codemap)
 
        for (i = 0; i < len; i++) {
                label = (rvm_codelabel_t*)r_array_slot(codemap->labels, i);
-               r_free(label->name.str);
+               r_free(label->name);
        }
        r_object_destroy((robject_t*)codemap->labels);
        r_object_destroy((robject_t*)codemap->hash);
@@ -66,9 +66,8 @@ static rlong rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint na
                labelidx = r_array_add(codemap->labels, NULL);
                label = rvm_codemap_label(codemap, labelidx);
                if (name) {
-                       label->name.str = r_strndup(name, namesize);
-                       label->name.size = namesize;
-                       r_hash_insert_indexval(codemap->hash, &label->name, labelidx);
+                       label->name = r_rstrdup(name, namesize);
+                       r_hash_insert_indexval(codemap->hash, label->name, labelidx);
                }
        }
        return labelidx;
@@ -175,3 +174,15 @@ rword rvm_codemap_resolve(rvm_codemap_t *codemap, rlong index, rvm_codelabel_t *
                *err = label;
        return (rword)-1;
 }
+
+
+void rvm_codemap_dump(rvm_codemap_t *codemap)
+{
+       rint i = 0;
+
+       for (i = 0; i < r_array_length(codemap->labels); i++) {
+               rvm_codelabel_t *label = rvm_codemap_label(codemap, i);
+               r_printf("%d: %s(%d), type: %d, base: %ld, value: %ld\n", i, label->name->str, label->name->size, label->type, label->base, label->value);
+       }
+}
+
index 40c5d47..1b1871d 100644 (file)
@@ -20,13 +20,12 @@ typedef struct rvm_codelabel_s {
        } type;
        rulong base;
        rword value;
-       rstr_t name;
+       rstr_t *name;
        rulong size; // Optional, used for function declarations
 } rvm_codelabel_t;
 
 
 typedef struct rvm_codemap_s {
-       rarray_t *blocks;
        rarray_t *labels;
        rhash_t *hash;
 } rvm_codemap_t;
@@ -46,6 +45,7 @@ rlong rvm_codemap_lookup_s(rvm_codemap_t *codemap, const rchar *name);
 rlong rvm_codemap_lastlabel(rvm_codemap_t *codemap);
 rvm_codelabel_t *rvm_codemap_label(rvm_codemap_t *codemap, rlong index);
 rword rvm_codemap_resolve(rvm_codemap_t *codemap, rlong index, rvm_codelabel_t **err);
+void rvm_codemap_dump(rvm_codemap_t *codemap);
 
 #ifdef __cplusplus
 }
index 06bc89d..bbe754b 100644 (file)
@@ -1963,12 +1963,30 @@ rint rvm_cpu_addswitable(rvmcpu_t *cpu, rvm_switable_t *switable)
 }
 
 
+rvm_asmins_t rvm_asma(rword opcode, rword op1, rword op2, rword op3, rchar *data, rulong size)
+{
+       rvm_asmins_t a;
+
+       r_memset(&a, 0, sizeof(a));
+       a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
+       a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
+       a.op1 = (ruint8)op1;
+       a.op2 = (ruint8)op2;
+       a.op3 = (ruint8)op3;
+       rvm_reg_setstrptr(&a.data, data, size);
+       if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
+               a.da = 1;
+       return a;
+}
+
+
 rvm_asmins_t rvm_asmp(rword opcode, rword op1, rword op2, rword op3, rpointer data)
 {
        rvm_asmins_t a;
 
        r_memset(&a, 0, sizeof(a));
-       a.opcode = (ruint8) opcode;
+       a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
+       a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
        a.op1 = (ruint8)op1;
        a.op2 = (ruint8)op2;
        a.op3 = (ruint8)op3;
@@ -1984,7 +2002,8 @@ rvm_asmins_t rvm_asms(rword opcode, rword op1, rword op2, rword op3, rword data)
        rvm_asmins_t a;
 
        r_memset(&a, 0, sizeof(a));
-       a.opcode = (ruint8) opcode;
+       a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
+       a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
        a.op1 = (ruint8)op1;
        a.op2 = (ruint8)op2;
        a.op3 = (ruint8)op3;
@@ -2001,7 +2020,8 @@ rvm_asmins_t rvm_asmf(rword opcode, rword op1, rword op2, rword op3, rword data)
        rvm_asmins_t a;
 
        r_memset(&a, 0, sizeof(a));
-       a.opcode = (ruint8) opcode;
+       a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
+       a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
        a.op1 = (ruint8)op1;
        a.op2 = (ruint8)op2;
        a.op3 = (ruint8)op3;
@@ -2116,33 +2136,6 @@ rvm_asmins_t rvm_asmx(rword opcode, rword op1, rword op2, rword op3, rpointer pR
 }
 
 
-//rvm_codelabel_t *rvm_relocate(rvm_asmins_t *code, rsize_t size)
-//{
-//     rvm_codelabel_t *label;
-//     rvm_asmins_t *reloc;
-//     rulong relocindex;
-//     rulong off;
-//
-//     for (off = 0; off < size; off++, code++) {
-//             if (code->flags & RVM_ASMINS_RELOC) {
-//                     label = (rvm_codelabel_t *)RVM_REG_GETP(&code->data);
-//                     if (label->type == RVM_CODELABEL_OFFSET) {
-//                             relocindex = label->loc.index;
-//                             RVM_REG_SETU(&code->data, relocindex - off);
-//                             code->flags &= ~RVM_ASMINS_RELOC;
-//                     } else if (label->type == RVM_CODELABEL_POINTER) {
-//                             reloc = (rvm_asmins_t *)label->loc.ptr;
-//                             RVM_REG_SETU(&code->data, reloc - code);
-//                             code->flags &= ~RVM_ASMINS_RELOC;
-//                     } else {
-//                             return label;
-//                     }
-//             }
-//     }
-//     return NULL;
-//}
-
-
 rvmreg_t *rvm_cpu_alloc_global(rvmcpu_t *cpu)
 {
        rvmreg_t *global;
index cc37677..8cb8da4 100644 (file)
@@ -93,7 +93,6 @@ extern "C" {
 #define RVM_CPUREG_GETPAIR(__cpu__, __r__) RVM_CPUREG_PTR(__cpu__, __r__)->v.pair
 #define RVM_CPUREG_SETPAIR(__cpu__, __r__, __val1__, __val2__) RVM_REG_SETPAIR(RVM_CPUREG_PTR(__cpu__, __r__), __val1__, __val2__)
 
-#define RVM_REG_GETSTRSIZE(__r__) (__r__)->size
 #define RVM_REG_GETSTR(__r__) (__r__)->v.s
 #define RVM_REG_SETSTR(__r__, __str__, __size__) do { (__r__)->v.s = (__str__); if ((__size__) == (ruint)-1) (__r__)->size = r_strlen(__str__); else (__r__)->size = (__size__);} while (0)
 #define RVM_CPUREG_GETSTR(__cpu__, __r__) RVM_REG_GETSTR(RVM_CPUREG_PTR(__cpu__, __r__))
@@ -107,7 +106,9 @@ extern "C" {
 #define RVM_CPUREG_SETIP(__cpu__, __r__, __val__) RVM_REG_SETIP(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
 #define RVM_CPUREG_INCIP(__cpu__, __r__, __val__) do {rvm_asmins_t *p = RVM_CPUREG_GETIP(__cpu__, __r__); (RVM_CPUREG_PTR(__cpu__, __r__))->v.p = (rpointer)(p + (__val__)); } while (0)
 
-#define RVM_REG_SIZE(__r__) (__r__)->size
+#define RVM_REG_GETSIZE(__r__) (__r__)->size
+#define RVM_CPUREG_GETSIZE(__cpu__, __r__) RVM_REG_GETSIZE(RVM_CPUREG_PTR(__cpu__, __r__))
+
 #define RVM_REG_CLEAR(__r__) do { (__r__)->v.w = 0UL; (__r__)->type = 0; (__r__)->flags = 0;  } while (0)
 #define RVM_CPUREG_CLEAR(__cpu__, __r__) RVM_REG_CLEAR(RVM_CPUREG_PTR(__cpu__, __r__))
 
index beabeb2..5fd692c 100644 (file)
@@ -16,6 +16,7 @@ rvm_relocmap_t *rvm_relocmap_create()
 void rvm_relocmap_destroy(rvm_relocmap_t *relocmap)
 {
        r_object_destroy((robject_t*)relocmap->records);
+       r_free(relocmap);
 }
 
 
index 2b89ec1..280e533 100644 (file)
@@ -64,7 +64,7 @@ int main(int argc, char *argv[])
 
        rvm_codemap_addpointer_s(codemap, ".code", &vmcode[0]);
        if (rvm_relocmap_relocate(relocmap, codemap, vmcode, &err) < 0) {
-               r_printf("Unresolved symbol: %s\n", err->name.str);
+               r_printf("Unresolved symbol: %s\n", err->name->str);
                goto end;
        }
 
index e59a9f5..2ca9e5e 100644 (file)
@@ -93,7 +93,7 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
 
        if (rvm_codegen_relocate(cg, &err) < 0) {
-               r_printf("Unresolved symbol: %s\n", err->name.str);
+               r_printf("Unresolved symbol: %s\n", err->name->str);
                goto end;
        }
        rvm_asm_dump(rvm_codegen_getcode(cg, 0), rvm_codegen_getcodesize(cg));
index ba4ae90..87df267 100644 (file)
@@ -13,7 +13,7 @@ void codelabel_print_info(rvm_codemap_t *codemap, rchar* name)
        if (!label)
                fprintf(stdout, "%s (not found)\n", name);
        else
-               fprintf(stdout, "%s, asmins: 0x%lx\n", label->name.str, (rulong)label->value);
+               fprintf(stdout, "%s, asmins: 0x%lx\n", label->name->str, (rulong)label->value);
 }
 
 
index 8b5731e..684ff28 100644 (file)
@@ -61,7 +61,7 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
 
        if (rvm_codegen_relocate(cg, &err) < 0) {
-               r_printf("Unresolved symbol: %s\n", err->name.str);
+               r_printf("Unresolved symbol: %s\n", err->name->str);
                goto end;
        }
 
index c2fe04c..6885a79 100644 (file)
@@ -31,6 +31,8 @@ static int compileonly = 0;
 #define RPA_SHIFT                      RVM_OPSWI(RVM_SWI_ID(regextable, 6))
 #define RPA_EQSHIFT                    RVM_OPSWI(RVM_SWI_ID(regextable, 7))
 #define RPA_NEQSHIFT           RVM_OPSWI(RVM_SWI_ID(regextable, 8))
+#define RPA_EMITSTART          RVM_OPSWI(RVM_SWI_ID(regextable, 9))
+#define RPA_EMITEND                    RVM_OPSWI(RVM_SWI_ID(regextable, 10))
 
 
 typedef struct rpa_compiler_s {
@@ -42,8 +44,9 @@ typedef struct rpa_compiler_s {
 
 
 typedef struct rpainput_s {
-       ruint32 wc;
        const rchar *input;
+       ruint32 wc;
+       ruchar eof;
 } rpainput_t;
 
 
@@ -83,6 +86,7 @@ void rpa_compiler_destroy(rpa_compiler_t *co)
                rvm_codegen_destroy(co->cg);
                rvm_scope_destroy(co->scope);
        }
+       r_free(co);
 }
 
 rpastat_t *rpa_stat_create()
@@ -132,23 +136,27 @@ 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);
+       rpainput_t * ptp = &stat->instack[tp];
 
-       if (stat->ip.input >= stat->end) {
-               RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, 1);
+       if (ptp->eof)
                return;
-       }
-
-       tp += 1;
+       ptp++;
+       tp++;
        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 += 1;
+               rint inc = 0;
+               ptp->input = stat->ip.input;
+               if (ptp->input < stat->end) {
+                       inc = r_utf8_mbtowc(&ptp->wc, (const ruchar*)stat->ip.input, (const ruchar*)stat->end);
+                       stat->ip.input += inc;
+                       stat->ip.serial += 1;
+                       ptp->eof = 0;
+               } else {
+                       ptp->wc = (ruint32)-1;
+                       ptp->eof = 1;
+               }
        }
        RVM_CPUREG_SETL(cpu, IP, stat->instack[tp].wc);
        RVM_CPUREG_SETL(cpu, TP, tp);
-       RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, 0);
 }
 
 
@@ -173,26 +181,26 @@ static void rpa_matchchr(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rword flags = RVM_CPUREG_GETU(cpu, ins->op2);
 
        if (flags == RPA_MATCH_OPTIONAL) {
-               RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!(cpu->status & RVM_STATUS_V) && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) ? 1 : 0);
+               RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!stat->instack[RVM_CPUREG_GETL(cpu, TP)].eof && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) ? 1 : 0);
                rpa_eqshift(cpu, ins);
        } else if (flags == RPA_MATCH_MULTIPLE) {
-               RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!(cpu->status & RVM_STATUS_V) && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) ? 1 : 0);
+               RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!stat->instack[RVM_CPUREG_GETL(cpu, TP)].eof && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) ? 1 : 0);
                if (cpu->status & RVM_STATUS_Z)
                        rpa_shift(cpu, ins);
-               while (!(cpu->status & RVM_STATUS_V) && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) {
+               while (!stat->instack[RVM_CPUREG_GETL(cpu, TP)].eof && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) {
                        rpa_shift(cpu, ins);
                }
 //             if (!(cpu->status & RVM_STATUS_Z))
 //                     RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, LR));
        } else if (flags == RPA_MATCH_MULTIOPT) {
                ruint matched = 0;
-               while (!(cpu->status & RVM_STATUS_V) && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) {
+               while (!stat->instack[RVM_CPUREG_GETL(cpu, TP)].eof && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) {
                        matched = 1;
                        rpa_shift(cpu, ins);
                }
                RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, matched);
        } else {
-               RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!(cpu->status & RVM_STATUS_V) && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) ? 1 : 0);
+               RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!stat->instack[RVM_CPUREG_GETL(cpu, TP)].eof && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) ? 1 : 0);
                rpa_eqshift(cpu, ins);
 //             if (!(cpu->status & RVM_STATUS_Z))
 //                     RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, LR));
@@ -220,7 +228,7 @@ static void rpa_matchrng(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rlong tp = RVM_CPUREG_GETL(cpu, TP);
        rpair_t op1 = RVM_CPUREG_GETPAIR(cpu, ins->op1);
 
-       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!(cpu->status & RVM_STATUS_V) && stat->instack[tp].wc >= op1.p1 && stat->instack[tp].wc <= op1.p2) ? 1 : 0);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!stat->instack[RVM_CPUREG_GETL(cpu, TP)].eof && stat->instack[tp].wc >= op1.p1 && stat->instack[tp].wc <= op1.p2) ? 1 : 0);
 }
 
 
@@ -238,7 +246,30 @@ static void rpa_neqmatchrng(rvmcpu_t *cpu, rvm_asmins_t *ins)
 }
 
 
+static void rpa_emitstart(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+//     rpastat_t *stat = (rpastat_t *)cpu->userdata1;
+       rword tp = RVM_CPUREG_GETU(cpu, ins->op2);
+       rstr_t name = {RVM_CPUREG_GETSTR(cpu, ins->op1), RVM_CPUREG_GETSIZE(cpu, ins->op1)};
+
+       r_printf("START: %s(%ld)\n", name.str, (rulong)tp);
+
+}
+
+
+static void rpa_emitend(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+//     rpastat_t *stat = (rpastat_t *)cpu->userdata1;
+       rword tp = RVM_CPUREG_GETU(cpu, ins->op2);
+       rword tplen = RVM_CPUREG_GETU(cpu, ins->op3);
+       rstr_t name = {RVM_CPUREG_GETSTR(cpu, ins->op1), RVM_CPUREG_GETSIZE(cpu, ins->op1)};
 
+       if (tplen) {
+               r_printf("MATCHED: %s(%ld, %ld): %p\n", name.str, (rulong)tp, (rulong)tplen, name.str);
+       } else {
+               r_printf("MATCHED: %s(%ld, %ld)\n", name.str, (rulong)tp, (rulong)tplen);
+       }
+}
 
 static rvm_switable_t switable[] = {
                {"RPA_MATCHCHR", rpa_matchchr},
@@ -250,6 +281,8 @@ static rvm_switable_t switable[] = {
                {"RPA_SHIFT", rpa_shift},
                {"RPA_EQSHIFT", rpa_eqshift},
                {"RPA_NEQSHIFT", rpa_neqshift},
+               {"RPA_EMITSTART", rpa_emitstart},
+               {"RPA_EMITEND", rpa_emitend},
                {NULL, NULL},
 };
 
@@ -287,10 +320,26 @@ void codegen_rpa_match_char(rpa_compiler_t *co, rword wc, rchar q)
 
 void codegen_rpa_match_abc(rpa_compiler_t *co)
 {
+       rulong rulename;
+
+       rvm_codegen_addstring_s(co->cg, NULL, "rpafdadf");
+       rvm_codegen_addstring_s(co->cg, "5", "rpad");
+       rvm_codegen_addstring_s(co->cg, NULL, "rpa_ma");
+       rulename = rvm_codegen_addstring_s(co->cg, "3", "rpa_match_ab");
+       rvm_codegen_addstring_s(co->cg, "4", "z");
+
+
        rvm_codegen_addlabel_s(co->cg, "rpa_match_abc");
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, TP, R0, XX, 0));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_DEFAULT, rulename, rvm_asma(RPA_EMITSTART, DA, TP, XX, 0, -1));
        codegen_rpa_match_char(co, 'a', ' ');
-       codegen_rpa_match_char(co, 'b', '?');
-       codegen_rpa_match_char(co, 'c', '+');
+       codegen_rpa_match_char(co, 'b', ' ');
+       codegen_rpa_match_char(co, 'c', '*');
+       codegen_rpa_match_char(co, 'd', '?');
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, R0, TP, R1, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_ELNOT, R2, R0, XX, 0));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_DEFAULT, rulename, rvm_asma(RPA_EMITEND, DA, R1, R0, 0, -1));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
 }
 
@@ -346,9 +395,8 @@ int main(int argc, char *argv[])
        codegen_rpa_match(co);
        codegen_rpa_match_abc(co);
 
-
        if (rvm_codegen_relocate(co->cg, &err) < 0) {
-               r_printf("Unresolved symbol: %s\n", err->name.str);
+               r_printf("Unresolved symbol: %s\n", err->name->str);
                goto end;
        }
 
@@ -366,12 +414,13 @@ int main(int argc, char *argv[])
                        rvm_cpu_exec(cpu, rvm_codegen_getcode(co->cg, 0), 0);
        }
 
-       r_printf("Matched: %d\n", ((rpastat_t *)cpu->userdata1)->ip.input - ((rpastat_t *)cpu->userdata1)->input);
+       r_printf("Matched: %d\n", ((rpastat_t *)cpu->userdata1)->instack[RVM_CPUREG_GETL(cpu, TP)].input - ((rpastat_t *)cpu->userdata1)->input);
 end:
        rpa_stat_destroy((rpastat_t *)cpu->userdata1);
        rvm_cpu_destroy(cpu);
+       rpa_compiler_destroy(co);
 
-       if (debuginfo) {
+       if (1||debuginfo) {
                r_printf("Max alloc mem: %ld\n", r_debug_get_maxmem());
                r_printf("Leaked mem: %ld\n", r_debug_get_allocmem());
        }
index 7e7d555..1d9c27b 100644 (file)
@@ -121,7 +121,7 @@ int main(int argc, char *argv[])
        rvm_codegen_funcend(cg);
 
        if (rvm_codegen_relocate(cg, &err) < 0) {
-               r_printf("Unresolved symbol: %s\n", err->name.str);
+               r_printf("Unresolved symbol: %s\n", err->name->str);
                goto end;
        }