1 #include "rvmcodemap.h"
6 rvm_codemap_t *rvm_codemap_create()
8 rvm_codemap_t *codemap;
10 codemap = (rvm_codemap_t*)r_malloc(sizeof(*codemap));
13 r_memset(codemap, 0, sizeof(*codemap));
14 codemap->labels = r_array_create(sizeof(rvm_codelabel_t));
15 codemap->hash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
20 void rvm_codemap_destroy(rvm_codemap_t *codemap)
23 rvm_codelabel_t *label;
24 rlong len = r_array_length(codemap->labels);
26 for (i = 0; i < len; i++) {
27 label = (rvm_codelabel_t*)r_array_slot(codemap->labels, i);
30 r_object_destroy((robject_t*)codemap->labels);
31 r_object_destroy((robject_t*)codemap->hash);
36 void rvm_codemap_clear(rvm_codemap_t *codemap)
39 rvm_codelabel_t *label;
41 for (i = 0; i < r_array_length(codemap->labels); i++) {
42 label = (rvm_codelabel_t*)r_array_slot(codemap->labels, i);
45 r_array_setlength(codemap->labels, 0);
46 r_hash_removeall(codemap->hash);
50 rvm_codelabel_t *rvm_codemap_label(rvm_codemap_t *codemap, rlong index)
52 if (index < 0 || index >= r_array_length(codemap->labels))
54 return (rvm_codelabel_t*)r_array_slot(codemap->labels, index);
58 static rlong rvm_codemap_dolookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
60 rstr_t lookupstr = {(char*)name, namesize};
61 return r_hash_lookup_indexval(codemap->hash, &lookupstr);
65 static rlong rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
67 rvm_codelabel_t *label;
70 labelidx = rvm_codemap_dolookup(codemap, name, namesize);
72 r_memset(&label, 0, sizeof(label));
73 labelidx = r_array_add(codemap->labels, NULL);
74 label = rvm_codemap_label(codemap, labelidx);
76 label->name = r_rstrdup(name, namesize);
77 r_hash_insert_indexval(codemap->hash, label->name, labelidx);
85 rlong rvm_codemap_addoffset(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rulong base, rulong offset)
87 rlong labelidx = rvm_codemap_add(codemap, name, namesize);
88 rvm_codelabel_t *label = rvm_codemap_label(codemap, labelidx);
92 label->value = offset;
93 label->type = RVM_CODELABEL_OFFSET;
99 rlong rvm_codemap_addoffset_s(rvm_codemap_t *codemap, const rchar *name, rulong base, rulong offset)
101 return rvm_codemap_addoffset(codemap, name, r_strlen(name), base, offset);
105 rlong rvm_codemap_addpointer(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rpointer ptr)
107 rlong labelidx = rvm_codemap_add(codemap, name, namesize);
108 rvm_codelabel_t *label = rvm_codemap_label(codemap, labelidx);
111 label->value = (rword)ptr;
112 label->type = RVM_CODELABEL_POINTER;
118 rlong rvm_codemap_addpointer_s(rvm_codemap_t *codemap, const rchar *name, rpointer ptr)
120 return rvm_codemap_addpointer(codemap, name, r_strlen(name), ptr);
124 rlong rvm_codemap_invalid_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
126 rlong labelidx = rvm_codemap_add(codemap, name, namesize);
127 rvm_codelabel_t *label = rvm_codemap_label(codemap, labelidx);
130 label->type = RVM_CODELABEL_INVALID;
136 rlong rvm_codemap_validindex(rvm_codemap_t *codemap, rlong labelidx)
138 rvm_codelabel_t *label = rvm_codemap_label(codemap, labelidx);
140 if (label && label->type != RVM_CODELABEL_INVALID)
146 rlong rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name)
148 return rvm_codemap_invalid_add(codemap, name, r_strlen(name));
152 rlong rvm_codemap_lastlabel(rvm_codemap_t *codemap)
154 return r_array_length(codemap->labels) - 1;
158 rlong rvm_codemap_lookupadd(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
160 rstr_t lookupstr = {(char*)name, namesize};
161 rlong labelidx = r_hash_lookup_indexval(codemap->hash, &lookupstr);
164 labelidx = rvm_codemap_invalid_add(codemap, name, namesize);
169 rlong rvm_codemap_lookupadd_s(rvm_codemap_t *codemap, const rchar *name)
171 return rvm_codemap_lookupadd(codemap, name, r_strlen(name));
175 rlong rvm_codemap_lookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
177 rstr_t lookupstr = {(char*)name, namesize};
178 rlong labelidx = r_hash_lookup_indexval(codemap->hash, &lookupstr);
184 rlong rvm_codemap_lookup_s(rvm_codemap_t *codemap, const rchar *name)
186 return rvm_codemap_lookup(codemap, name, r_strlen(name));
190 rword rvm_codemap_resolve(rvm_codemap_t *codemap, rlong index, rvm_codelabel_t **err)
192 rvm_codelabel_t *label = rvm_codemap_label(codemap, index);
197 if (label->type == RVM_CODELABEL_POINTER) {
199 } else if (label->type == RVM_CODELABEL_OFFSET) {
200 value = rvm_codemap_resolve(codemap, label->base, err);
201 if (value == (rword)-1)
203 return value + label->value;
211 void rvm_codemap_dump(rvm_codemap_t *codemap)
215 for (i = 0; i < r_array_length(codemap->labels); i++) {
216 rvm_codelabel_t *label = rvm_codemap_label(codemap, i);
217 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);