bc.c (5762B)
1 #include <stdlib.h> 2 #include <stdio.h> 3 4 #include "bc.h" 5 6 #include "fh.h" 7 #include "var.h" 8 #include "helper.h" 9 #include "is.h" 10 #include "ins_def.h" 11 12 /* Handles allocation for new `bc_cont` instances 13 */ 14 void bc_cont_new(bc_cont* new) 15 { 16 //new = (bc_cont*)malloc(sizeof(bc_cont)); 17 M_ASSERT(new); 18 19 new->args[0] = NULL; 20 new->args[1] = NULL; 21 new->args[2] = NULL; 22 23 new->varg[0] = NULL; 24 new->varg[1] = NULL; 25 new->varg[2] = NULL; 26 27 new->sarg[0] = 0; 28 new->sarg[1] = 0; 29 new->sarg[2] = 0; 30 } 31 32 void bc_cont_del(bc_cont* ins) 33 { 34 if (ins != NULL) 35 { 36 if (ins->args[0] != NULL) free(ins->args[0]); 37 if (ins->args[1] != NULL) free(ins->args[1]); 38 if (ins->args[2] != NULL) free(ins->args[2]); 39 40 if (ins->varg[0] != NULL) var_del(ins->varg[0]); 41 if (ins->varg[1] != NULL) var_del(ins->varg[1]); 42 if (ins->varg[2] != NULL) var_del(ins->varg[2]); 43 } 44 } 45 46 /* Given a file object, and an instance of `bc_cont` with proper metadata, this 47 * function will read arguements into bc_cont. 48 * 49 * 'bc_cont' proper metadata is generated by 50 */ 51 void get_opcode_adata(FILE* f, bc_cont* ins) 52 { 53 int num_args, 54 arg_types[3]; 55 56 // `is.h`-> unencode 57 unencode(ins->mdata, &num_args, arg_types); 58 59 int x; 60 for (x = 0; x < num_args; x++) 61 { 62 // A_BYTE -> byte-length arguement 63 if (arg_types[x] == A_BYTE) 64 { 65 ins->args[x] = get_byte_arg(f, &ins->sarg[x]); 66 } else 67 // A_NAME -> name-length arguement 68 if (arg_types[x] == A_NAME) 69 { 70 ins->args[x] = get_name_arg(f, &ins->sarg[x]); 71 } else 72 // A_ADDR -> address-length arguement 73 if (arg_types[x] == A_ADDR) 74 { 75 ins->args[x] = get_addr_arg(f, &ins->sarg[x]); 76 } else 77 // A_DYNC -> dynamic-length arguement 78 if (arg_types[x] == A_DYNC) 79 { 80 ins->args[x] = get_dync_arg(f, &ins->sarg[x]); 81 } 82 } 83 } 84 byte_t* get_byte_arg(FILE* f, int* size) 85 { 86 *size = 1; 87 return read_bytes(f, 1); 88 } 89 byte_t* get_name_arg(FILE* f, int* size) 90 { 91 *size = NAMELEN; 92 return read_bytes(f, NAMELEN); 93 } 94 byte_t* get_addr_arg(FILE* f, int* size) 95 { 96 *size = ADDRLEN; 97 return read_bytes(f, ADDRLEN); 98 } 99 byte_t* get_dync_arg(FILE* f, int* size) 100 { 101 int n = 0; 102 103 byte_t byte = read_byte(f); 104 105 // This bit gets the length in bytes it needs to read into a buffer 106 // NOTE: 107 // There are certain 'holes' where, a certain number, ex. 108 // 0xFF00, 0xFF0001, 0xFFFF00, etc 109 // will yeild improper values due to the while loop below encountering 110 // a null octet prematurely. 111 // Numbers that work are the following: 112 // 0xFF01, 0xFF0101, 0xFFFF01 113 // Whenever a seralizer is using dynamic arguements the seralizer must 114 // implement a method that asserts if a number is such that each octet 115 // does not equal 0. For a given bitwidth, the set of numbers is 116 // described roughly: 117 // { <valid octets> | !(0 in <octets>) } 118 // if the length of the body of a set of bytes is a member of 119 // <valid octets>, it can work with this function. 120 while (byte != 0) 121 { 122 n = (n << 8 | byte); 123 byte = read_byte(f); 124 } 125 126 *size = n; 127 128 return read_bytes(f, n); 129 } 130 131 /* Given an instruction, convert raw arguement data into typed data 132 * bc_cont* - bytecode container 133 */ 134 void process_args(bc_cont* ins) 135 { 136 int num_args, 137 arg_types[3]; 138 139 // `is.h`-> unencode 140 unencode(ins->adata, &num_args, arg_types); 141 142 int x; 143 for (x = 0; x < num_args; x++) 144 { 145 if (arg_types[x] == BTOI) 146 { 147 ins->varg[x] = raw_to_int(ins->sarg[x], 0, ins->args[x], 0); 148 } else 149 if (arg_types[x] == BTOT) 150 { 151 ins->varg[x] = byte_to_type(ins->args[x][0], 0); 152 } else 153 if (arg_types[x] == DTOL) 154 { 155 ins->varg[x] = raw_to_plist(ins->sarg[x], ins->args[x], 0); 156 } else 157 if (arg_types[x] == DTOV) 158 { 159 ins->varg[x] = raw_to_var(ins->sarg[x], ins->args[x], 0); 160 } 161 } 162 } 163 164 /* Reads program into bc_cont instances 165 * FILE* - File descriptor 166 * bc_addr* - pointer to size variable 167 */ 168 bc_cont* bc_read(FILE* f, bc_addr* len) 169 { 170 N_ASSERT(f, "bc_read\n"); 171 172 long fsize = read_size(f); 173 174 bc_addr addr = 0; 175 bc_cont* ptr; 176 byte_t byte; 177 178 bc_cont* heap = (bc_cont*)malloc(sizeof(bc_cont)*fsize); 179 N_ASSERT(heap, "bc_read\n"); 180 181 /* Loop through file byte-by-byte */ 182 while (ftell(f) < fsize) 183 { 184 ptr = &heap[addr]; 185 // Creates a new bc_cont instance 186 bc_cont_new(ptr); 187 // Gets the opcode 188 byte = read_byte(f); 189 // Gets opcode metadata 190 get_opcode_mdata(byte, ptr); 191 // Gets opcode arguement metadata 192 get_opcode_adata(f, ptr); 193 // Process raw arguements 194 process_args(ptr); 195 196 // Set the real address of instruction 197 heap[addr].real_addr = addr; 198 199 // Increment address 200 addr++; 201 } 202 203 *len = addr; 204 return heap; 205 } 206 207 /* Reads program into bc_t instance 208 * char* - filename 209 */ 210 bc_t* bc_init(char* fname) 211 { 212 N_ASSERT(fname, "bc_init\n"); 213 214 FILE* f; 215 216 bc_t* program; 217 218 f = fopen(fname, "rb"); 219 220 program = (bc_t*)malloc(sizeof(bc_t)); 221 N_ASSERT(program, "bc_read\n"); 222 223 // Read bytecode into array of bc_cont* 224 program->heap = bc_read(f, &program->size); 225 226 fclose(f); 227 228 return program; 229 } 230 231 /* Deletes instance of bc_t* 232 */ 233 void bc_del(bc_t* program) 234 { 235 N_ASSERT(program, "bc_del\n"); 236 237 int i; 238 for (i=0; i < program->size; i++) 239 { 240 bc_cont_del(&program->heap[i]); 241 } 242 243 free(program->heap); 244 245 free(program); 246 } 247 248 /* Thing for pretty printing 249 */ 250 void bc_print_op(bc_cont* op) 251 { 252 int num_args, 253 arg_types[3]; 254 255 unencode(op->mdata, &num_args, arg_types); 256 257 printf("%s [%x] - ", INS_DESC[op->op], op->op); 258 for (int i = 0; i < num_args && num_args != 0; i++) 259 { 260 if (arg_types[i] == A_BYTE) 261 { 262 printf("I:<%02x>, ", op->args[i][0]); 263 } else 264 if (arg_types[i] == A_NAME) 265 { 266 printf("N:<%02x%02x>, ", op->args[i][0], op->args[i][1]); 267 } else 268 if (arg_types[i] == A_DYNC) 269 { 270 printf("DYN[%02x]: ", op->sarg[i]); 271 for (int x = 0; x < op->sarg[i]; x++) 272 printf("%02x ", op->args[i][x]); 273 } 274 } 275 } 276