/* Creates a segment of desired size, intializes all words to 0 and returns the * identifier. */ ID_SIZE Segment_map(T seg_memory, unsigned size) { //Invariant at work here in the 'if' case WORD_SIZE *seg = malloc(sizeof(WORD_SIZE) * (size + 1)); for (WORD_SIZE i = 0; i < (size + 1); i++) { seg[i] = 0; } assert(seg != NULL); seg[0] = size; ID_SIZE id, i; Seq_T segments = seg_memory->segments; Seq_T unmapped = seg_memory->unmapped_ids; ID_SIZE unmapped_length = Seq_length(unmapped); ID_SIZE segs_length = Seq_length(segments); /* If there aren't any more unmapped id's, we replenish the unmapped id * sequence with MAP_INCREMENT amount. */ if (unmapped_length == 0) { for (i = segs_length; i < segs_length + MAP_INCREMENT; i++) { Seq_addhi(unmapped, (void *)(uintptr_t)i); } } id = (ID_SIZE)(uintptr_t)Seq_remlo(unmapped); if (id >= segs_length) { Seq_addhi(segments, seg); } else { Seq_put(segments, id, seg); } return id; }
void verifyMapped(Seq_T memorySegments, Seq_T unmappedSegments) { assert(Seq_length(memorySegments) == Seq_length(unmappedSegments)); for(int i = 0; i < Seq_length(memorySegments); i++){ if(Seq_get(memorySegments, i) == Seq_get(unmappedSegments, i)){ fprintf(stderr, "Cannot be both mapped and unmapped: %d\n", i); /* if(Seq_get(unmappedSegments, i) == NULL) { fprintf(stderr, "Both NULL\n"); }*/ exit(1); } if(Seq_get(memorySegments, i) != NULL) { if(Seq_get(unmappedSegments, i) != NULL){ fprintf(stderr, "Failed to unmap index: %d\n", i); exit(1); } UArray_T temp = Seq_get(memorySegments, i); for(UM_Word j = 0; j < (UM_Word)UArray_length(temp); j++) { UM_Word value = *(UM_Word*)UArray_at(temp, j); if(value != 0){ printf("Segmented load at %d with value of %u\n", i, value); } } } } printf("Verified\n"); }
/* * Input: Mem_T structure, unsigned integer * Output: returns the index at which the segment was stored. * Purpose: Adds a segment to memory with numWords words. */ int map_segment(Mem_T memory, unsigned numWords) { int segIndex; int reusedTest = 0; if(Seq_length(memory->reusable_indices) > 0){ segIndex = (int)(intptr_t)Seq_remlo(memory->reusable_indices); reusedTest = 1; } else segIndex = Seq_length(memory->segment_seq); Seq_T segment = Seq_new(numWords); uint32_t initializer = 0; for(unsigned i = 0; i < numWords; i++){ Seq_addhi(segment, (void *)(uintptr_t)initializer); } if(reusedTest) { Seq_put(memory->segment_seq, segIndex, segment); } else { Seq_addhi(memory->segment_seq, segment); } return segIndex; }
static void free_address_space(UM_machine machine) { UM_address_space address_space = machine->address_space; /* free the mapped segments sequence */ int length = Seq_length(address_space->mapped_segments); for(int i=0; i<length; i++){ UM_segment segment = Seq_remlo(address_space->mapped_segments); /* if segment with ID == i is mapped, free it */ if(segment != NULL){ free_segment_memory(&segment); } } Seq_free(&address_space->mapped_segments); /* free the reusable IDs sequence */ for(int i=0; i<Seq_length(address_space->reusable_IDs); i++){ UM_segment_ID *seg_ID = Seq_get(address_space->reusable_IDs, i); free(seg_ID); } Seq_free(&(address_space->reusable_IDs)); free(address_space); }
/* stabend - emits the symbol table */ static void stabend(Coordinate *cp, Symbol symroot, Coordinate *cpp[], Symbol sp[], Symbol *ignore) { Symbol addresses; int naddresses, nmodule; { /* annotate top-level symbols */ Symbol p; for (p = symroot; p != NULL; p = up(p->up)) symboluid(p); pickle->globals = symboluid(symroot); } { /* emit addresses of top-level and static symbols */ int i, lc = 0, count = Seq_length(statics); addresses = genident(STATIC, array(voidptype, 1, 0), GLOBAL); comment("addresses:\n"); defglobal(addresses, LIT); for (i = 0; i < count; i++) { Symbol p = Seq_get(statics, i); lc = emit_value(lc, voidptype, p); } lc = pad(maxalign, lc); naddresses = lc; Seq_free(&statics); } { /* emit bp count as an alias for the module */ Symbol spoints = mksymbol(AUTO, stringf("_spoints_V%x_%d", uname, Seq_length(pickle->spoints)), array(unsignedtype, 0, 0)); spoints->generated = 1; defglobal(spoints, LIT); } { /* emit module */ int lc; comment("module:\n"); defglobal(module, LIT); lc = emit_value( 0, unsignedtype, (unsigned long)uname); lc = emit_value(lc, voidptype, addresses); lc = pad(maxalign, lc); nmodule = lc; } Seq_free(&locals); #define printit(x) fprintf(stderr, "%7d " #x "\n", n##x); total += n##x { int total = 0; printit(addresses); printit(module); fprintf(stderr, "%7d bytes total\n", total); } #undef printit { /* complete and write symbol-table pickle */ FILE *f = fopen(stringf("%d.pickle", uname), "wb"); sym_write_module(pickle, f); fclose(f); } }
void emit_goto_test(Seq_T stream) { int patch_L = Seq_length(stream); emit(stream, loadval(r7, 0)); /* will be patched to 'r7 := L' */ emit(stream, loadprogram(r0, r7)); /* should goto label L */ emit_out_string(stream, "GOTO failed.\n", r1); emit(stream, halt()); /* define 'L' to be here */ add_label(stream, patch_L, Seq_length(stream)); emit_out_string(stream, "GOTO passed.\n", r1); emit(stream, halt()); }
/* * a new segment is created with number of words equal to what is * in register rC, each word is initialized to zero, and the new ID is * placed in register rB */ extern void segMem_map(segment_data* segments, Seq_T freed_mem, uint32_t* regs, uint32_t* tail, uint32_t* num_segments, int rc_size, int rb_id) { segment_data new_segment = NULL; /* reusage of freed segment identifiers of available */ if (Seq_length(freed_mem) > 0) { int* id = ((int*) Seq_remlo(freed_mem)); new_segment = init_segment(regs, rc_size); segments[*id] = new_segment; regs[rb_id] = *id; free(id); } /* creates a new segment if an old one is not available */ else { uint32_t id = *(tail); new_segment = init_segment(regs, rc_size); assert(new_segment); assert(segments); segments[id] = new_segment; assert(segments[0]); regs[rb_id] = id; *(tail) = id + 1; /* resizing */ if ((*tail) >= (*num_segments)) { segment_data* new_segments = realloc(segments, 2*sizeof(segment_data)*(*num_segments)); if (new_segments != NULL) { segments = new_segments; *(num_segments) = *(num_segments) * 2; } } } }
void verifyMapped(Seq_T memorySegments, Seq_T unmappedSegments) { // Verifies that the available unmapped segments is updated upon mapping for(int i = 0; i < Seq_length(unmappedSegments); i++){ UM_Word index = *(UM_Word*)Seq_get(unmappedSegments, i); if((UArray_T)Seq_get(memorySegments, index) != NULL){ fprintf(stderr, "Unmapped segments not updated correctly for: %u\n", index); exit(1); } } for(int i = 0; i < MEM_SEG_LEN; i++) { UArray_T segments = (UArray_T)Seq_get(memorySegments, i); if (segments != NULL) { for(int j = 0; j < UArray_length(segments); j++) { // Each 32-bit word must be initialized to 0 printf("memseg: %u\n", *(UM_Word*)UArray_at(segments, j)); if(*(UM_Word*)UArray_at(segments, j) != 0) { fprintf(stderr, "segment incorrectly initialized\n"); exit(1); } } } } printf("Verified bitch.\n"); }
void map_segment(int A, int B, int C) { // fprintf(stderr, "in map seg\n"); (void) A; uint32_t c = register_at(C); Seg_array seg_array = initialize_seg_array((int)c); uint32_t id = 0; // fprintf(stderr, "before resize\n"); if (SEG_NUM + 1 >= SEG_LENGTH){ // fprintf(stderr, "in resize\n"); resize_seg_mem(SEG_LENGTH * 2); } // fprintf(stderr, "after resize\n"); if (Seq_length(UNMAP_SEG) == 0){ id = SEG_NUM + 1; SEG_NUM++; } else { id = (uint32_t)(uintptr_t)Seq_remlo(UNMAP_SEG); } assign_to_register(id, B); // fprintf(stderr, "id: %u, seg_num: %d, mem_length: %d\n", id, SEG_NUM, UArray_length(SEG_MEMORY)); SEG_MEMORY[id] = seg_array; //fprintf(stderr, "after seg\n"); }
bool put_word(Segment s, uint32_t ID, uint32_t address, uint32_t word) { TRY assert(s); UArray_T inner = Seq_get(s, ID); assert(inner); if (ID >= (unsigned) Seq_length(s)) { /* ID does not exist */ return false; } if (address >= (unsigned) UArray_length(inner)) { /* offset does not exist */ return false; } assert(inner); uint32_t *wordptr = UArray_at(inner, address); *wordptr = word; EXCEPT(Mem_Failed) return false; END_TRY; return true; }
/* * Initializes the program counter and returns the number of instructions. */ void mapProgram(FILE* program) { Seq_T words = Seq_new(PROGRAM_HINT); int c = getc(program); while(c != EOF) { UM_Word temp = 0; temp = Bitpack_newu(temp, 8, 24, c); for(int bit = 16; bit >=0; bit -=8){ int b = getc(program); temp = Bitpack_newu(temp, 8, bit, b); } UM_Word* instr; NEW(instr); *instr = temp; Seq_addhi(words, instr); c = getc(program); } mapSegment(memorySegments, 0); mapInstructions(Seq_length(words)); int length = instructionLength(); for(int locToLoad = 0; locToLoad < length; locToLoad++){ UM_Word* value = (UM_Word*)Seq_get(words, locToLoad); loadInstruction(locToLoad, *value); FREE(value); } Seq_free(&words); }
MP_T pop(void) { if (Seq_length(sp) > 0) return Seq_remhi(sp); else { Fmt_fprint(stderr, "?stack underflow\n"); return MP_new(0); } }
/* call_hook - called at function calls. If *e is a call, call_hook changes the expression to the equivalent of the C expression (tos.ip = i, *e) where i is the stopping point index for the execution point of the expression in which the call appears. */ static void call_hook(void *cl, Coordinate *cp, Tree *e) { assert(*e); *e = tree(RIGHT, (*e)->type, asgntree(ASGN, field(lvalue(idtree(tos)), string("ip")), cnsttree(inttype, Seq_length(pickle->spoints))), *e); }
/* symboluid - returns sym's uid, adding the symbol, if necessary */ static int symboluid(const Symbol p) { int uid; sym_symbol_ty sym; if (p == NULL) return 0; sym = Table_get(uidTable, p); if (sym != NULL) return sym->uid; uid = pickle->nuids++; switch (p->sclass) { case ENUM: sym = sym_ENUMCONST(p->name, uid, uname, NULL, 0, 0, p->u.value); sym->type = typeuid(inttype); break; case TYPEDEF: sym = sym_TYPEDEF(p->name, uid, uname, NULL, 0, 0); sym->type = typeuid(p->type); break; default: if (p->sclass == STATIC) { sym = sym_STATIC(p->name, uid, uname, NULL, 0, 0, Seq_length(statics)); Seq_addhi(statics, p); } else if (p->scope == GLOBAL || p->sclass == EXTERN) { sym = sym_GLOBAL(p->name, uid, uname, NULL, 0, 0, Seq_length(statics)); Seq_addhi(statics, p); } else if (p->scope == PARAM) sym = sym_PARAM(p->name, uid, uname, NULL, 0, 0, p->x.offset); else { assert(p->scope >= LOCAL); sym = sym_LOCAL(p->name, uid, uname, NULL, 0, 0, p->x.offset); } sym->type = typeuid(p->type); } Table_put(uidTable, p, sym); Seq_addhi(pickle->items, sym_Symbol(uid, sym)); sym->src = sym_coordinate(p->src.file ? p->src.file : string(""), p->src.x, p->src.y); sym->uplink = symboluid(up(p->up)); return sym->uid; }
__declspec(dllexport) void curl_shim_free_strings(void* p) { int i, count; Seq_T seq = (Seq_T)p; count = Seq_length(seq); for (i = 0; i < count; i++) free(Seq_get(seq, i)); Seq_free(&seq); }
static bool has(Seq_T sequence, int n) { if (Seq_length(sequence) >= n) return true; else { printf("Stack underflow---expected at least %d element%s\n", n, n == 1 ? "" : "s"); return false; } }
/* free the mem */ void free_mem(Mem* myMem) { assert(myMem != NULL); for (int i = 0; i < Seq_length((*myMem)->segs); i++) { Seg_free(Seq_get((*myMem)->segs, i)); } Seq_free(&((*myMem)->segs)); Stack_free(&((*myMem)->unmapped)); free(*myMem); }
/* * Input: Mem_T structure * Output: void * Purpose: Frees all memory. Frees each segment, the sequence of segments, * the sequence of reusable indices and the pointer to the memory * structure */ void MemT_free(Mem_T memory){ int length = Seq_length(memory->segment_seq); for(int i = 0; i < length; i++){ Seq_T segment = Seq_get(memory->segment_seq, i); if(segment != NULL) Seq_free(&segment); } Seq_free(&(memory->segment_seq)); Seq_free(&(memory->reusable_indices)); free(memory); }
/* Frees all segmented memory created by the program, including the segment * where the program is stored. */ void Segment_free(T * seg_memory) { int len = Seq_length((*seg_memory)->segments); int i; for (i = 0; i < len; i++) { free(Seq_get((*seg_memory)->segments, i)); } Seq_free(&((*seg_memory)->segments)); Seq_free(&((*seg_memory)->unmapped_ids)); free (*seg_memory); }
/* point_hook - called at each execution point */ static void point_hook(void *cl, Coordinate *cp, Tree *e) { Tree t; /* add breakpoint test to *e: (_Nub_bpflags[i] != 0 && _Nub_bp(i), *e) */ t = tree(AND, voidtype, (*optree[NEQ])(NE, rvalue((*optree['+'])(ADD, pointer(idtree(nub_bpflags)), cnsttree(inttype, Seq_length(pickle->spoints)))), cnsttree(inttype, 0L)), vcall(nub_bp, voidtype, cnsttree(inttype, Seq_length(pickle->spoints)), NULL)); if (*e) *e = tree(RIGHT, (*e)->type, t, *e); else *e = t; Seq_addhi(pickle->spoints, sym_spoint(sym_coordinate(cp->file ? cp->file : string(""), cp->x, cp->y), tail())); }
void unblack (Bit2_T bitmap, int cur_x, int cur_y) { int w_pixels = Bit2_width (bitmap); int h_pixels = Bit2_height (bitmap); Seq_T point_queue = Seq_new(w_pixels*h_pixels); assert(point_queue); assert(0 <= cur_x && cur_x < w_pixels); assert(0 <= cur_y && cur_y < h_pixels); if (Bit2_get(bitmap, cur_x, cur_y) != 1) { // if pixel is white assert(point_queue); Seq_free(&point_queue); return; } else { Seq_addhi(point_queue, (void*)makePoint(cur_x,cur_y)); while (Seq_length(point_queue) > 0) { PointPair temp = (PointPair)Seq_remlo(point_queue); assert(temp); int i = temp->i; int j = temp->j; freePoint(temp); if (Bit2_get(bitmap, i, j) == 1) { // if current is black pixel Bit2_put(bitmap, i, j, 0); // set current to white assert(0 <= i && i < w_pixels); assert(0 <= j && j < h_pixels); if (j != 0 && j != h_pixels-1) { // if not a top/bottom pixel if (i+1 < w_pixels && Bit2_get(bitmap, i+1, j) == 1) { // if Seq_addhi(point_queue, (void*)makePoint(i+1,j)); } if (i > 0 && Bit2_get(bitmap, i-1, j) == 1) { Seq_addhi(point_queue, (void*)makePoint(i-1,j)); } } if (i != 0 && i != w_pixels-1) { if (j+1 < h_pixels && Bit2_get(bitmap, i, j+1) == 1) { Seq_addhi(point_queue, (void*)makePoint(i,j+1)); } if (j > 0 && Bit2_get(bitmap, i, j-1) == 1) { Seq_addhi(point_queue, (void*)makePoint(i,j-1)); } } } } assert(point_queue); Seq_free(&point_queue); return; } }
void Um_write_sequence(FILE *output, Seq_T stream) { while(Seq_length(stream) != 0){ union Instruction instruction; instruction.instruction = (Um_instruction)(uintptr_t)Seq_remlo(stream); for(int i = 3; i >= 0; i--){ putc(instruction.bytes[i], output); } } }
/* frees all of the segments and their contents */ void free_all(Segment outer) { assert(outer); int num_segs = Seq_length(outer); for (int i = 0; i < num_segs; i++) { UArray_T inner = Seq_get(outer, i); UArray_free(&inner); } Seq_free(&outer); }
UArray_T get_seg(Segment s, uint32_t ID) { assert(s); if (ID > (uint32_t) Seq_length(s)) { /* segment does not exist */ return NULL; } UArray_T inner = Seq_get(s, ID); return inner; }
static int checkuid(list_ty list) { int i, n = 0, count = Seq_length(list); for (i = 0; i < count; i++) { rcc_interface_ty in = Seq_get(list, i); if (in->kind == rcc_Local_enum || in->kind == rcc_Address_enum) n++; else if (in->kind == rcc_Function_enum) n += checkuid(in->v.rcc_Function.codelist); } return n; }
static void asdl_progend(void) { dopending(NULL); { int n = checkuid(pickle->interfaces) + Seq_length(pickle->items); if (n != pickle->nuids - 1) fprintf(stderr, "?bogus uid count: have %d should have %d\n", n, pickle->nuids-1); } pickle->nlabels = genlabel(0); write_int((int)(100*(assert(strstr(rcsid, ",v")), strtod(strstr(rcsid, ",v")+2, NULL)) ), stdout); rcc_write_program(pickle, stdout); }
/* * Frees all the memory associated with the Segment Manager * Parameter: sm - The Segment Manager Struct */ void segment_Free(Segment_Manager sm) { Segment nextsegment; while (Seq_length(sm->Segment_Table) != 0) { nextsegment = (UArray_T)Seq_remhi(sm->Segment_Table); if (nextsegment != NULL) UArray_free(&nextsegment); }; Seq_free(&(sm->Segment_Table)); Seq_free(&(sm->ID_Stack)); free(sm); return; }
/* * halt: Computation stops and deletes all memory that is allocated. */ void halt(Seq_T segMem, Seq_T delMem, uint32_t *arr) { while (Seq_length(segMem) != 0) { struct segment *s = Seq_remlo(segMem); if (s != NULL) { free(s->mem); free(s); } } Seq_free(&segMem); Seq_free(&delMem); free(arr); exit(EXIT_SUCCESS); }
/* * Helper function: Takes in a segment manager and a segment to insert, grabs * an id to associate with that segment, and puts it in the * table. * Parameters: sm - Segment Manager struct * segment - Segment to insert * Return value: The id of the newly inserted segment */ unsigned insert_Segment(Segment_Manager sm, Segment segment) { unsigned id; if (Seq_length(sm->ID_Stack) != 0) { id = (unsigned)(uintptr_t)Seq_remhi(sm->ID_Stack); Seq_put(sm->Segment_Table, id, segment); } else { Seq_addhi(sm->Segment_Table, segment); id = sm->ID_counter; sm->ID_counter++; } return id; }
/* * Input: Mem_T structure, unsigned integer * Ouput: void * Purpose: Copies the segment located at segIndex and stores it in segment 0 * The segment previously at index 0 is freed. */ void load_program(Mem_T memory, unsigned segIndex) { /*Segment that will become new program*/ Seq_T program_to_load_temp = Seq_get(memory->segment_seq, segIndex); int length = Seq_length(program_to_load_temp); /*New sequence that will be put in segment 0*/ Seq_T program_to_load = Seq_new(length); /*Copies program_to_load_temp to program_to_load*/ for(int i = 0; i < length; i++) { Seq_addhi(program_to_load, Seq_get(program_to_load_temp, i)); } Seq_T old_program = Seq_put(memory->segment_seq, 0, program_to_load); Seq_free(&old_program); }