RPA Toolkit
fixed the relocation mechanism
authorMartin Stoilov <martin@rpasearch.com>
Wed, 16 Feb 2011 07:41:19 +0000 (23:41 -0800)
committerMartin Stoilov <martin@rpasearch.com>
Wed, 16 Feb 2011 07:41:19 +0000 (23:41 -0800)
14 files changed:
rvm/rvmcodegen.c
rvm/rvmcodegen.h
rvm/rvmcodemap.c
rvm/rvmcodemap.h
rvm/rvmcpu.c
rvm/rvmcpu.h
rvm/rvmrelocmap.c
rvm/rvmrelocmap.h
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 368439b..f730d34 100644 (file)
@@ -13,6 +13,7 @@ rvm_codegen_t *rvm_codegen_create()
        r_memset(cg, 0, sizeof(*cg));
        cg->code = r_array_create(sizeof(rvm_asmins_t));
        cg->codemap = rvm_codemap_create();
+       cg->relocmap = rvm_relocmap_create();
        return cg;
 }
 
@@ -20,6 +21,7 @@ rvm_codegen_t *rvm_codegen_create()
 void rvm_codegen_destroy(rvm_codegen_t *cg)
 {
        rvm_codemap_destroy(cg->codemap);
+       rvm_relocmap_destroy(cg->relocmap);
        r_object_destroy((robject_t*)cg->code);
        r_free(cg);
 }
@@ -55,6 +57,51 @@ ruint rvm_codegen_addins(rvm_codegen_t *cg, rvm_asmins_t ins)
 }
 
 
+rlong rvm_codegen_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize)
+{
+       return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
+}
+
+
+rlong rvm_codegen_addlabel_s(rvm_codegen_t *cg, const rchar* name)
+{
+       return rvm_codegen_addlabel(cg, name, r_strlen(name));
+}
+
+
+ruint rvm_codegen_addlabelins(rvm_codegen_t *cg, const rchar* name, ruint namesize, rvm_asmins_t ins)
+{
+       rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
+       return rvm_codegen_addins(cg, ins);
+}
+
+
+ruint rvm_codegen_addlabelins_s(rvm_codegen_t *cg, const rchar* name, rvm_asmins_t ins)
+{
+       return rvm_codegen_addlabelins(cg, name, r_strlen(name), ins);
+}
+
+
+ruint rvm_codegen_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, ruint namesize, rvm_asmins_t ins)
+{
+       rvm_relocmap_add(cg->relocmap, type, rvm_codegen_getcodesize(cg), rvm_codemap_lookup(cg->codemap, name, namesize));
+       return rvm_codegen_addins(cg, 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);
+}
+
+
+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));
+       return rvm_relocmap_relocate(cg->relocmap, cg->codemap, (rvm_asmins_t *)r_array_slot(cg->code, 0), err);
+}
+
+
 ruint rvm_codegen_insertins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
 {
        return r_array_insert(cg->code, index, &ins);
@@ -72,10 +119,10 @@ ruint rvm_codegen_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize
 {
        ruint start;
        rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
-       start = rvm_codegen_addins(cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
+       start = rvm_codegen_addlabelins(cg, name, namesize, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
        rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, DA, args));
-       rvm_codemap_addoffset(cg->codemap, rvm_codemap_lookup_s(cg->codemap, ".code"), name, namesize, start);
+//     rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), start);
        return start;
 }
 
@@ -90,10 +137,10 @@ ruint rvm_codegen_vargs_funcstart(rvm_codegen_t *cg, const rchar* name, ruint na
 {
        ruint start;
        rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
-       start = rvm_codegen_addins(cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
+       start = rvm_codegen_addlabelins(cg, name, namesize, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
        rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, R0, 0));
-       rvm_codemap_addoffset(cg->codemap, rvm_codemap_lookup_s(cg->codemap, ".code"), name, namesize, start);
+//     rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), start);
        return start;
 }
 
index f705aef..a66cf41 100644 (file)
@@ -7,7 +7,7 @@
 #include "rhash.h"
 #include "rvmcpu.h"
 #include "rvmcodemap.h"
-
+#include "rvmrelocmap.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -20,6 +20,7 @@ typedef struct rvm_codegen_s {
        rarray_t *code;
        ruint codeoff;
        rvm_codemap_t *codemap;
+       rvm_relocmap_t *relocmap;
 } rvm_codegen_t;
 
 
@@ -31,12 +32,19 @@ ruint rvm_codegen_vargs_funcstart(rvm_codegen_t *cg, const rchar* name, ruint na
 ruint rvm_codegen_vargs_funcstart_s(rvm_codegen_t *cg, const rchar* name);
 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_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);
 ruint rvm_codegen_replaceins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins);
 rvm_asmins_t *rvm_codegen_getcode(rvm_codegen_t *cg, ruint index);
 rulong rvm_codegen_getcodesize(rvm_codegen_t *cg);
 void rvm_codegen_setcodesize(rvm_codegen_t *cg, ruint size);
 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);
 
 #ifdef __cplusplus
 }
index 917a2cf..43624d7 100644 (file)
@@ -11,8 +11,7 @@ rvm_codemap_t *rvm_codemap_create()
        if (!codemap)
                return NULL;
        r_memset(codemap, 0, sizeof(*codemap));
-       codemap->blocks = r_array_create(sizeof(rvm_loopblock_t));
-       codemap->labels = r_array_create(sizeof(rvm_codelabel_t*));
+       codemap->labels = r_array_create(sizeof(rvm_codelabel_t));
        codemap->hash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
        return codemap;
 }
@@ -25,12 +24,9 @@ void rvm_codemap_destroy(rvm_codemap_t *codemap)
        int len = r_array_length(codemap->labels);
 
        for (i = 0; i < len; i++) {
-               label = r_array_index(codemap->labels, i, rvm_codelabel_t*);
-               r_free(label->name);
-               r_free(label);
+               label = (rvm_codelabel_t*)r_array_slot(codemap->labels, i);
+               r_free(label->name.str);
        }
-
-       r_object_destroy((robject_t*)codemap->blocks);
        r_object_destroy((robject_t*)codemap->labels);
        r_object_destroy((robject_t*)codemap->hash);
        r_free(codemap);
@@ -48,7 +44,7 @@ rvm_codelabel_t *rvm_codemap_label(rvm_codemap_t *codemap, rlong index)
 {
        if (index < 0)
                return NULL;
-       return r_array_index(codemap->labels, index, rvm_codelabel_t*);
+       return (rvm_codelabel_t*)r_array_slot(codemap->labels, index);
 }
 
 
@@ -66,11 +62,13 @@ static rlong rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint na
 
        labelidx = rvm_codemap_dolookup(codemap, name, namesize);
        if (labelidx < 0) {
-               label = r_zmalloc(sizeof(*label));
-               labelidx = r_array_add(codemap->labels, &label);
+               r_memset(&label, 0, sizeof(label));
+               labelidx = r_array_add(codemap->labels, NULL);
+               label = rvm_codemap_label(codemap, labelidx);
                if (name) {
-                       label->name = r_rstrdup(name, namesize);
-                       r_hash_insert_indexval(codemap->hash, label->name, labelidx);
+                       label->name.str = r_strndup(name, namesize);
+                       label->name.size = namesize;
+                       r_hash_insert_indexval(codemap->hash, &label->name, labelidx);
                }
        }
        return labelidx;
@@ -78,40 +76,40 @@ static rlong rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint na
 
 
 
-rlong rvm_codemap_addoffset(rvm_codemap_t *codemap, rulong base, const rchar *name, ruint namesize, rulong offset)
+rlong rvm_codemap_addoffset(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rulong base, rulong offset)
 {
        rlong labelidx = rvm_codemap_add(codemap, name, namesize);
        rvm_codelabel_t *label = rvm_codemap_label(codemap, labelidx);
 
        if (label) {
                label->base = base;
-               label->loc.index = offset;
-               label->type = RVM_CODELABEL_INDEX;
+               label->value = offset;
+               label->type = RVM_CODELABEL_OFFSET;
        }
        return labelidx;
 }
 
 
-rlong rvm_codemap_addoffset_s(rvm_codemap_t *codemap, rulong base, const rchar *name, rulong offset)
+rlong rvm_codemap_addoffset_s(rvm_codemap_t *codemap, const rchar *name, rulong base, rulong offset)
 {
-       return rvm_codemap_addoffset(codemap, base, name, r_strlen(name), offset);
+       return rvm_codemap_addoffset(codemap, name, r_strlen(name), base, offset);
 }
 
 
-rlong rvm_codemap_addpointer(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rvm_asmins_t *ptr)
+rlong rvm_codemap_addpointer(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rpointer ptr)
 {
        rlong labelidx = rvm_codemap_add(codemap, name, namesize);
        rvm_codelabel_t *label = rvm_codemap_label(codemap, labelidx);
 
        if (label) {
-               label->loc.ptr = ptr;
+               label->value = (rword)ptr;
                label->type = RVM_CODELABEL_POINTER;
        }
        return labelidx;
 }
 
 
-rlong rvm_codemap_addpointer_s(rvm_codemap_t *codemap, const rchar *name, rvm_asmins_t *ptr)
+rlong rvm_codemap_addpointer_s(rvm_codemap_t *codemap, const rchar *name, rpointer ptr)
 {
        return rvm_codemap_addpointer(codemap, name, r_strlen(name), ptr);
 }
@@ -158,3 +156,22 @@ rlong rvm_codemap_lookup_s(rvm_codemap_t *codemap, const rchar *name)
 }
 
 
+rword rvm_codemap_resolve(rvm_codemap_t *codemap, rlong index, rvm_codelabel_t **err)
+{
+       rvm_codelabel_t *label = rvm_codemap_label(codemap, index);
+       rword value;
+
+       if (!label)
+               return 0;
+       if (label->type == RVM_CODELABEL_POINTER) {
+               return label->value;
+       } else if (label->type == RVM_CODELABEL_OFFSET) {
+               value = rvm_codemap_resolve(codemap, label->base, err);
+               if (value == (rword)-1)
+                       return (rword)-1;
+               return value + label->value;
+       }
+       if (err)
+               *err = label;
+       return (rword)-1;
+}
index 038f5b6..40c5d47 100644 (file)
 extern "C" {
 #endif
 
-typedef struct rvm_loopblock_s {
-       rulong begin;
-       rulong size;
-} rvm_loopblock_t;
-
 
 typedef struct rvm_codelabel_s {
        enum {
-               RVM_CODELABEL_INDEX = 0,
+               RVM_CODELABEL_OFFSET = 0,
                RVM_CODELABEL_POINTER,
                RVM_CODELABEL_INVALID,
        } type;
        rulong base;
-       union {
-               rulong index;
-               rpointer ptr;
-       } loc;
-       rstr_t *name;
+       rword value;
+       rstr_t name;
        rulong size; // Optional, used for function declarations
 } rvm_codelabel_t;
 
@@ -45,15 +37,15 @@ void rvm_codemap_destroy(rvm_codemap_t *codemap);
 void rvm_codemap_clear(rvm_codemap_t *codemap);
 rlong rvm_codemap_invalid_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize);
 rlong rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name);
-rlong rvm_codemap_addoffset(rvm_codemap_t *codemap, rulong base, const rchar *name, ruint namesize, rulong offset);
-rlong rvm_codemap_addoffset_s(rvm_codemap_t *codemap, rulong base, const rchar *name, rulong offset);
-rlong rvm_codemap_addpointer(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rvm_asmins_t *ptr);
-rlong rvm_codemap_addpointer_s(rvm_codemap_t *codemap, const rchar *name, rvm_asmins_t *ptr);
+rlong rvm_codemap_addoffset(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rulong base, rulong offset);
+rlong rvm_codemap_addoffset_s(rvm_codemap_t *codemap, const rchar *name, rulong base, rulong offset);
+rlong rvm_codemap_addpointer(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rpointer ptr);
+rlong rvm_codemap_addpointer_s(rvm_codemap_t *codemap, const rchar *name, rpointer ptr);
 rlong rvm_codemap_lookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize);
 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);
 
 #ifdef __cplusplus
 }
index 0736552..06bc89d 100644 (file)
@@ -2126,7 +2126,7 @@ rvm_asmins_t rvm_asmx(rword opcode, rword op1, rword op2, rword op3, rpointer pR
 //     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_INDEX) {
+//                     if (label->type == RVM_CODELABEL_OFFSET) {
 //                             relocindex = label->loc.index;
 //                             RVM_REG_SETU(&code->data, relocindex - off);
 //                             code->flags &= ~RVM_ASMINS_RELOC;
index 1548673..72704ad 100644 (file)
@@ -255,7 +255,8 @@ do { \
 #define RVM_STACK_READ(__s__, __sp__) *RVM_STACK_ADDR(__s__, __sp__)
 #define RVM_STACK_ADDR(__s__, __sp__) (((rvmreg_t*)(__s__)) + (__sp__))
 #define RVM_STACK_CHECKSIZE(__cpu__, __s__, __sp__)  ((__sp__) < (__cpu__)->stacksize ? 1 : 0)
-
+#define RVM_CODE2BYTE_OFFSET(__codeoff__) ((rword)(((rsword)(__codeoff__)) * ((rsword)sizeof(rvm_asmins_t))))
+#define RVM_BYTE2CODE_OFFSET(__byteoff__) ((rword)(((rsword)(__byteoff__)) / ((rsword)sizeof(rvm_asmins_t))))
 
 #define RVM_E_DIVZERO          (1)
 #define RVM_E_ILLEGAL          (2)
index e9decb2..beabeb2 100644 (file)
@@ -25,15 +25,14 @@ void rvm_relocmap_clear(rvm_relocmap_t *relocmap)
 }
 
 
-rvm_relocrecord_t *rvm_relocmap_add(rvm_relocmap_t *relocmap, rulong offset, rulong label)
+rlong rvm_relocmap_add(rvm_relocmap_t *relocmap, rvm_reloctype_t type, rulong offset, rulong label)
 {
        rvm_relocrecord_t record;
-       rint index;
+       record.type = type;
        record.offset = offset;
        record.label = label;
 
-       index = r_array_add(relocmap->records, &record);
-       return (rvm_relocrecord_t *)r_array_slot(relocmap->records, index);
+       return r_array_add(relocmap->records, &record);
 }
 
 
@@ -51,18 +50,24 @@ rulong rvm_relocmap_length(rvm_relocmap_t *relocmap)
 }
 
 
-rlong rvm_relocmap_relocate(rvm_relocmap_t *relocmap, rvm_codemap_t *codemap, rvm_asmins_t *code)
+rint rvm_relocmap_relocate(rvm_relocmap_t *relocmap, rvm_codemap_t *codemap, rvm_asmins_t *code, rvm_codelabel_t **err)
 {
        rlong index;
-       rvm_codelabel_t *label;
        rvm_relocrecord_t *reloc;
+       rword value;
 
        for (index = 0; index < r_array_length(relocmap->records); index++) {
                reloc = rvm_relocmap_get(relocmap, index);
-               label = rvm_codemap_label(codemap, reloc->label);
-               if (label == NULL || label->type == RVM_CODELABEL_INVALID)
-                       return index;
-               code[reloc->offset].data.v.u64 = (ruint64)(code + label->loc.index);
+               value = rvm_codemap_resolve(codemap, reloc->label, err);
+               if (value == (rword)-1)
+                       return -1;
+               if (reloc->type == RVM_RELOC_BRANCH) {
+                       code[reloc->offset].data.v.w = RVM_BYTE2CODE_OFFSET(value - (rword)&code[reloc->offset]);
+               } else if (reloc->type == RVM_RELOC_JUMP) {
+                       code[reloc->offset].data.v.w = value - RVM_CODE2BYTE_OFFSET(1);
+               } else {
+                       code[reloc->offset].data.v.w = value;
+               }
        }
-       return -1;
+       return 0;
 }
index 11145bb..5738d28 100644 (file)
 extern "C" {
 #endif
 
+typedef enum {
+       RVM_RELOC_DEFAULT = 0,
+       RVM_RELOC_JUMP,
+       RVM_RELOC_BRANCH,
+} rvm_reloctype_t;
+
 
 typedef struct rvm_relocrecord_s {
+       rvm_reloctype_t type;
        rulong offset;
        rulong label;
 } rvm_relocrecord_t;
@@ -27,10 +34,10 @@ typedef struct rvm_relocmap_s {
 rvm_relocmap_t *rvm_relocmap_create();
 void rvm_relocmap_destroy(rvm_relocmap_t *relocmap);
 void rvm_relocmap_clear(rvm_relocmap_t *relocmap);
-rvm_relocrecord_t *rvm_relocmap_add(rvm_relocmap_t *relocmap, rulong offset, rulong label);
+rlong rvm_relocmap_add(rvm_relocmap_t *relocmap, rvm_reloctype_t type, rulong offset, rulong label);
 rvm_relocrecord_t *rvm_relocmap_get(rvm_relocmap_t *relocmap, rulong index);
 rulong rvm_relocmap_length(rvm_relocmap_t *relocmap);
-rlong rvm_relocmap_relocate(rvm_relocmap_t *relocmap, rvm_codemap_t *codemap, rvm_asmins_t *code);
+rint rvm_relocmap_relocate(rvm_relocmap_t *relocmap, rvm_codemap_t *codemap, rvm_asmins_t *code, rvm_codelabel_t **err);
 
 
 #ifdef __cplusplus
index 2e5fb20..2b89ec1 100644 (file)
@@ -10,19 +10,20 @@ int main(int argc, char *argv[])
        ruint ret = 0;
        ruint off = 0;
        rvm_asmins_t vmcode[256];
+       rvm_codelabel_t *err = NULL;
        rvmcpu_t *vm = rvm_cpu_create_default();
        rvm_codemap_t *codemap = rvm_codemap_create();
        rvm_relocmap_t *relocmap = rvm_relocmap_create();
 
        rvm_cpu_addswitable(vm, common_calltable);
 
-       rvm_relocmap_add(relocmap, off, rvm_codemap_lookup_s(codemap, "l_main"));
-       vmcode[off++]   = rvm_asmx(RVM_BX,   DA, XX, XX, rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, "l_main")));
+       rvm_relocmap_add(relocmap, RVM_RELOC_BRANCH, off, rvm_codemap_lookup_s(codemap, "l_main"));
+       vmcode[off++]   = rvm_asm(RVM_B,   DA, XX, XX, 0);
 
        /*
         * R0 = R0 + R1
         */
-       rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "l_add2", off - 1);
+       rvm_codemap_addoffset_s(codemap, "l_add2", rvm_codemap_lookup_s(codemap, ".code"), RVM_CODE2BYTE_OFFSET(off));
        vmcode[off++] = rvm_asm(RVM_ADD, R0, R0, R1, 0);
        vmcode[off++] = rvm_asm(RVM_RET, XX, XX, XX, 0);
 
@@ -30,14 +31,14 @@ int main(int argc, char *argv[])
        /*
         * R0 = R0 + R1 + R2
         */
-       rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "l_add3", off - 1);
+       rvm_codemap_addoffset_s(codemap, "l_add3", rvm_codemap_lookup_s(codemap, ".code"), RVM_CODE2BYTE_OFFSET(off));
        vmcode[off++] = rvm_asm(RVM_PUSHM,DA, XX, XX, BIT(R7)|BIT(R8)|BIT(SP)|BIT(LR));
        vmcode[off++] = rvm_asm(RVM_PUSH, R2, XX, XX, 0);
-       rvm_relocmap_add(relocmap, off, rvm_codemap_lookup_s(codemap, "l_add2"));
-       vmcode[off++] = rvm_asmx(RVM_BXL,   DA, XX, XX, rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, "l_add2")));
+       rvm_relocmap_add(relocmap, RVM_RELOC_JUMP, off, rvm_codemap_lookup_s(codemap, "l_add2"));
+       vmcode[off++] = rvm_asm(RVM_BXL,   DA, XX, XX, 0);
        vmcode[off++] = rvm_asm(RVM_POP,  R1, XX, XX, 0);
-       rvm_relocmap_add(relocmap, off, rvm_codemap_lookup_s(codemap, "l_add2"));
-       vmcode[off++] = rvm_asmx(RVM_BXL,   DA, XX, XX, rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, "l_add2")));
+       rvm_relocmap_add(relocmap, RVM_RELOC_JUMP, off, rvm_codemap_lookup_s(codemap, "l_add2"));
+       vmcode[off++] = rvm_asm(RVM_BXL,   DA, XX, XX, 0);
        vmcode[off++] = rvm_asm(RVM_POPM, DA, XX, XX, BIT(R7)|BIT(R8)|BIT(SP)|BIT(LR));
        vmcode[off++] = rvm_asm(RVM_RET,  XX, XX, XX, 0);
        /*
@@ -47,27 +48,33 @@ int main(int argc, char *argv[])
         *
         */
 
-       rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "l_main", off - 1);
+       rvm_codemap_addoffset_s(codemap, "l_main", rvm_codemap_lookup_s(codemap, ".code"), RVM_CODE2BYTE_OFFSET(off));
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 2);
-       rvm_relocmap_add(relocmap, off, rvm_codemap_lookup_s(codemap, "l_add2"));
-       vmcode[off++] = rvm_asmx(RVM_BXL,  DA, XX, XX, rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, "l_add2")));
+       rvm_relocmap_add(relocmap, RVM_RELOC_JUMP, off, rvm_codemap_lookup_s(codemap, "l_add2"));
+       vmcode[off++] = rvm_asmx(RVM_BXL,  DA, XX, XX, 0);
        VMTEST_REG(vmcode, off, 0, 3, "BL/RET");
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 2);
        vmcode[off++] = rvm_asm(RVM_MOV, R2, DA, XX, 4);
-       rvm_relocmap_add(relocmap, off, rvm_codemap_lookup_s(codemap, "l_add3"));
-       vmcode[off++] = rvm_asmx(RVM_BXL,  DA, XX, XX, rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, "l_add3")));
+       rvm_relocmap_add(relocmap, RVM_RELOC_JUMP, off, rvm_codemap_lookup_s(codemap, "l_add3"));
+       vmcode[off++] = rvm_asmx(RVM_BXL,  DA, XX, XX, 0);
        VMTEST_REG(vmcode, off, 0, 7, "BL/RET");
        vmcode[off++] = rvm_asm(RVM_EXT, R0, XX, XX, 0);
 
-       rvm_relocmap_relocate(relocmap, codemap, vmcode);
+       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);
+               goto end;
+       }
 
 #ifdef EXECDEBUG
        ret = rvm_cpu_exec_debug(vm, vmcode, 0);
 #else
        ret = rvm_cpu_exec(vm, vmcode, 0);
 #endif
+
+end:
        rvm_cpu_destroy(vm);
        rvm_codemap_destroy(codemap);
        rvm_relocmap_destroy(relocmap);
index 2008e53..e59a9f5 100644 (file)
@@ -21,6 +21,7 @@ int main(int argc, char *argv[])
 {
        rvmcpu_t *cpu;
        rvm_codegen_t *cg;
+       rvm_codelabel_t *err;
        ruint ntable;
 
        cg = rvm_codegen_create();
@@ -34,7 +35,7 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 9));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 3 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 3));
-       rvm_codegen_addins(cg, rvm_asmx(RVM_BL,  DA, XX, XX, rvm_codemap_lookup_s(cg->codemap, "add3")));
+       rvm_codegen_addrelocins_s(cg, RVM_RELOC_JUMP, "add3", rvm_asm(RVM_BXL,  DA, XX, XX, 0));
        rvm_codegen_addins(cg, rvm_asm(RVM_OPSWI(RVM_SWI_ID(ntable, 0)), R0, XX, XX, 0));
 
 
@@ -47,7 +48,7 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 4));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 4 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 4));
-       rvm_codegen_addins(cg, rvm_asmx(RVM_BL,  DA, XX, XX, rvm_codemap_lookup_s(cg->codemap, "varadd")));
+       rvm_codegen_addrelocins_s(cg, RVM_RELOC_BRANCH, "varadd", rvm_asm(RVM_BL,  DA, XX, XX, 0));
        rvm_codegen_addins(cg, rvm_asm(RVM_OPSWI(RVM_SWI_ID(ntable, 0)), R0, XX, XX, 0));
 
 
@@ -65,13 +66,14 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 1 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R1, SP, DA, 2 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 2));
-       rvm_codegen_addins(cg, rvm_asmx(RVM_BL,  DA, XX, XX, rvm_codemap_lookup_s(cg->codemap, "add2")));
+       rvm_codegen_addrelocins_s(cg, RVM_RELOC_BRANCH, "add2", rvm_asm(RVM_BL,  DA, XX, XX, 0));
 
        rvm_codegen_addins(cg, rvm_asm(RVM_LDS, R1, FP, DA, 3));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 1 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R1, SP, DA, 2 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 2));
-       rvm_codegen_addins(cg, rvm_asmx(RVM_BL,  DA, XX, XX, rvm_codemap_lookup_s(cg->codemap, "add2")));
+       rvm_codegen_addrelocins_s(cg, RVM_RELOC_BRANCH, "add2", rvm_asm(RVM_BL,  DA, XX, XX, 0));
+
        rvm_codegen_funcend(cg);
 
        rvm_codegen_vargs_funcstart_s(cg, "varadd");
@@ -90,9 +92,14 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
        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);
+               goto end;
+       }
        rvm_asm_dump(rvm_codegen_getcode(cg, 0), rvm_codegen_getcodesize(cg));
-
        rvm_cpu_exec_debug(cpu, rvm_codegen_getcode(cg, 0), 0);
+
+end:
        rvm_cpu_destroy(cpu);
        rvm_codegen_destroy(cg);
 
index 9bbd827..ba4ae90 100644 (file)
@@ -8,13 +8,12 @@
 
 void codelabel_print_info(rvm_codemap_t *codemap, rchar* name)
 {
-       rvm_codelabel_t *label;
+       rvm_codelabel_t *label = rvm_codemap_label(codemap, rvm_codemap_lookup_s(codemap, name));
 
-       label = rvm_codemap_lookup_s(codemap, name);
        if (!label)
                fprintf(stdout, "%s (not found)\n", name);
        else
-               fprintf(stdout, "%s, asmins: 0x%d\n", label->name->str, (ruint)label->loc.index);
+               fprintf(stdout, "%s, asmins: 0x%lx\n", label->name.str, (rulong)label->value);
 }
 
 
@@ -22,9 +21,9 @@ int main(int argc, char *argv[])
 {
        rvm_codemap_t *codemap = rvm_codemap_create();
 
-       rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "add2", 0);
-       rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "add3", 3);
-       rvm_codemap_addoffset_s(codemap, rvm_codemap_lookup_s(codemap, ".code"), "sub2", 7);
+       rvm_codemap_addoffset_s(codemap, "add2", rvm_codemap_lookup_s(codemap, ".code"), 0);
+       rvm_codemap_addoffset_s(codemap, "add3", rvm_codemap_lookup_s(codemap, ".code"), 3);
+       rvm_codemap_addoffset_s(codemap, "sub2", rvm_codemap_lookup_s(codemap, ".code"), 7);
 
        codelabel_print_info(codemap, "add2");
        codelabel_print_info(codemap, "add7");
index 181af3a..8b5731e 100644 (file)
@@ -33,6 +33,7 @@ int main(int argc, char *argv[])
 {
        rvmcpu_t *cpu;
        rvm_codegen_t *cg;
+       rvm_codelabel_t *err;
        ruint ntable;
 
        cg = rvm_codegen_create();
@@ -43,7 +44,8 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 1 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 8));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 2 + RVM_CODEGEN_FUNCINITOFFSET));
-       rvm_codegen_addins(cg, rvm_asmx(RVM_BL,  DA, XX, XX, rvm_codemap_lookup_s(cg->codemap, "add2")));
+       rvm_codegen_addrelocins_s(cg, RVM_RELOC_BRANCH, "add2", rvm_asm(RVM_BL,  DA, XX, XX, 0));
+
        rvm_codegen_addins(cg, rvm_asm(RVM_OPSWI(rvm_cpu_getswi_s(cpu, "print")), R0, XX, XX, 0));
 
        rvm_codegen_addins(cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
@@ -58,9 +60,14 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
        rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
 
-       rvm_asm_dump(rvm_codegen_getcode(cg, 0), rvm_codegen_getcodesize(cg));
+       if (rvm_codegen_relocate(cg, &err) < 0) {
+               r_printf("Unresolved symbol: %s\n", err->name.str);
+               goto end;
+       }
 
+       rvm_asm_dump(rvm_codegen_getcode(cg, 0), rvm_codegen_getcodesize(cg));
        rvm_cpu_exec_debug(cpu, rvm_codegen_getcode(cg, 0), 0);
+end:
        rvm_cpu_destroy(cpu);
        rvm_codegen_destroy(cg);
 
index f2969bd..c2fe04c 100644 (file)
@@ -144,7 +144,7 @@ static void rpa_shift(rvmcpu_t *cpu, rvm_asmins_t *ins)
                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;
+               stat->ip.serial += 1;
        }
        RVM_CPUREG_SETL(cpu, IP, stat->instack[tp].wc);
        RVM_CPUREG_SETL(cpu, TP, tp);
@@ -256,17 +256,7 @@ static rvm_switable_t switable[] = {
 
 void codegen_rpa_match(rpa_compiler_t *co)
 {
-       rulong off, l1, l2;
-
-       rvm_scope_addoffset_s(co->scope, "rpa_match", co->fpoff);
-       l1 = rvm_codegen_getcodesize(co->cg);
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R1, FP, DA, co->fpoff++));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, R0, PC, DA, sizeof(rvm_asmins_t) * 3));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_SETTYPE, R0, DA, XX, RVM_DTYPE_FUNCTION));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
-       l2 = rvm_codegen_getcodesize(co->cg);
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0));                                                      /* Will be re-written later */
-       rvm_codemap_addoffset_s(co->cg->codemap, rvm_codemap_lookup_s(co->cg->codemap, ".code"), "rpa_match", rvm_codegen_getcodesize(co->cg));
+       rvm_codegen_addlabel_s(co->cg, "rpa_match");
        rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(TP)|BIT(FP)|BIT(SP)|BIT(LR)));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, R0, XX, XX, 0));
@@ -276,8 +266,6 @@ void codegen_rpa_match(rpa_compiler_t *co)
        rvm_codegen_addins(co->cg, rvm_asm(RVM_ORR, R0, R0, DA, BIT(TP)));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, R0, XX, XX, 0));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
-       off = rvm_codegen_getcodesize(co->cg);
-       rvm_codegen_replaceins(co->cg, l2, rvm_asm(RVM_B, DA, XX, XX, off - l2));
 }
 
 
@@ -299,32 +287,18 @@ void codegen_rpa_match_char(rpa_compiler_t *co, rword wc, rchar q)
 
 void codegen_rpa_match_abc(rpa_compiler_t *co)
 {
-       rulong off, l1, l2;
-
-       rvm_scope_addoffset_s(co->scope, "rpa_match_abc", co->fpoff);
-       l1 = rvm_codegen_getcodesize(co->cg);
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R1, FP, DA, co->fpoff++));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, R0, PC, DA, sizeof(rvm_asmins_t) * 3));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_SETTYPE, R0, DA, XX, RVM_DTYPE_FUNCTION));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
-       l2 = rvm_codegen_getcodesize(co->cg);
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0));                                                      /* Will be re-written later */
-       rvm_codemap_addoffset_s(co->cg->codemap, rvm_codemap_lookup_s(co->cg->codemap, ".code"), "rpa_match_abc", rvm_codegen_getcodesize(co->cg));
+       rvm_codegen_addlabel_s(co->cg, "rpa_match_abc");
        codegen_rpa_match_char(co, 'a', ' ');
        codegen_rpa_match_char(co, 'b', '?');
        codegen_rpa_match_char(co, 'c', '+');
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
-       off = rvm_codegen_getcodesize(co->cg);
-       rvm_codegen_replaceins(co->cg, l2, rvm_asm(RVM_B, DA, XX, XX, off - l2));
-
-
 }
 
 
 int main(int argc, char *argv[])
 {
        rvmcpu_t *cpu;
-       rvm_codelabel_t *unresolved;
+       rvm_codelabel_t *err;
        rpa_compiler_t *co;
        rint i;
 
@@ -354,9 +328,6 @@ int main(int argc, char *argv[])
        }
 
 
-       codegen_rpa_match(co);
-       codegen_rpa_match_abc(co);
-
        rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, TP, DA, XX, -1));
        rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, FP, DA, XX, 0));
        rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, SP, DA, XX, co->fpoff));
@@ -366,16 +337,21 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_MOP, DA, XX, RPA_MATCH_MULTIOPT));
 
        rvm_codegen_addins(co->cg, rvm_asm(RPA_SHIFT, XX, XX, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R4, DA, XX, rvm_scope_lookup_s(co->scope, "rpa_match")->data.offset));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R0, DA, XX, rvm_scope_lookup_s(co->scope, "rpa_match_abc")->data.offset));
-
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, R4, XX, XX, 0));
-//     rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, R0, PC, DA, (rvm_codegen_getcodesize(co->cg) - rvm_codemap_lookup_s(co->cg->codemap, "rpa_match_abc")->loc.index  + 1) * sizeof(rvm_asmins_t)));
-//     rvm_codegen_addins(co->cg, rvm_asmx(RVM_BL, DA, XX, XX, rvm_codemap_lookup_s(co->cg->codemap, "rpa_match")));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpa_match_abc", rvm_asm(RVM_MOV, R0, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpa_match", rvm_asm(RVM_BL, DA, XX, XX, 0));
 
        rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xabc));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
 
+       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);
+               goto end;
+       }
+
        if (debuginfo) {
                fprintf(stdout, "\nGenerated Code:\n");
                rvm_asm_dump(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
@@ -390,6 +366,7 @@ 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);
 end:
        rpa_stat_destroy((rpastat_t *)cpu->userdata1);
        rvm_cpu_destroy(cpu);
index 6a21db1..7e7d555 100644 (file)
@@ -70,6 +70,7 @@ int main(int argc, char *argv[])
 
        rvm_testctx_t ctx;
        rvm_codegen_t *cg;
+       rvm_codelabel_t *err;
        rvmcpu_t *cpu;
        rvm_opmap_t *opmap;
        ruint ntable;
@@ -88,14 +89,14 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 1 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asml(RVM_MOV, R0, DA, XX, r_strlen(hello)));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 2 + RVM_CODEGEN_FUNCINITOFFSET));
-       rvm_codegen_addins(cg, rvm_asmx(RVM_BL,  DA, XX, XX, rvm_codemap_lookup_s(cg->codemap, "str_init")));
+       rvm_codegen_addrelocins_s(cg, RVM_RELOC_BRANCH, "str_init", rvm_asm(RVM_BL,  DA, XX, XX, 0));
        rvm_codegen_addins(cg, rvm_asmp(RVM_MOV, R7, R0, XX, 0));
 
        rvm_codegen_addins(cg, rvm_asmp(RVM_MOV, R0, DA, XX, there));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 1 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asml(RVM_MOV, R0, DA, XX, r_strlen(there)));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 2 + RVM_CODEGEN_FUNCINITOFFSET));
-       rvm_codegen_addins(cg, rvm_asmx(RVM_BL,  DA, XX, XX, rvm_codemap_lookup_s(cg->codemap, "str_init")));
+       rvm_codegen_addrelocins_s(cg, RVM_RELOC_BRANCH, "str_init", rvm_asm(RVM_BL,  DA, XX, XX, 0));
        rvm_codegen_addins(cg, rvm_asmp(RVM_MOV, R8, R0, XX, 0));
 
        rvm_codegen_addins(cg, rvm_asmp(RVM_MOV, R0, R7, XX, 0));
@@ -119,7 +120,14 @@ int main(int argc, char *argv[])
        rvm_codegen_addins(cg, rvm_asm(RVM_OPSWI(rvm_cpu_getswi_s(cpu, "str_to_double")), R0, R0, XX, 0));
        rvm_codegen_funcend(cg);
 
+       if (rvm_codegen_relocate(cg, &err) < 0) {
+               r_printf("Unresolved symbol: %s\n", err->name.str);
+               goto end;
+       }
+
        rvm_cpu_exec_debug(cpu, rvm_codegen_getcode(cg, 0), 0);
+
+end:
        rvm_cpu_destroy(cpu);
        rvm_opmap_destroy(opmap);
        rvm_codegen_destroy(cg);