static int typeuid(Type ty) { rcc_type_ty type; assert(ty); if (ty->x.typeno != 0) return ty->x.typeno; ty->x.typeno = pickle->nuids++; switch (ty->op) { #define xx(op) case op: type = rcc_##op(ty->size, ty->align); break xx(INT); xx(UNSIGNED); xx(FLOAT); xx(VOID); #undef xx #define xx(op) case op: type = rcc_##op(ty->size, ty->align, typeuid(ty->type)); break xx(POINTER); xx(ARRAY); xx(CONST); xx(VOLATILE); #undef xx case CONST+VOLATILE: type = rcc_CONST(ty->size, ty->align, typeuid(ty->type)); break; case ENUM: { list_ty ids = Seq_new(0); int i; for (i = 0; ty->u.sym->u.idlist[i] != NULL; i++) Seq_addhi(ids, rcc_enum_(ty->u.sym->u.idlist[i]->name, ty->u.sym->u.idlist[i]->u.value)); assert(i > 0); type = rcc_ENUM(ty->size, ty->align, ty->u.sym->name, ids); break; } case STRUCT: case UNION: { list_ty fields = Seq_new(0); Field p = fieldlist(ty); for ( ; p != NULL; p = p->link) Seq_addhi(fields, rcc_field(p->name, typeuid(p->type), p->offset, p->bitsize, p->lsb)); if (ty->op == STRUCT) type = rcc_STRUCT(ty->size, ty->align, ty->u.sym->name, fields); else type = rcc_UNION (ty->size, ty->align, ty->u.sym->name, fields); break; } case FUNCTION: { list_ty formals = Seq_new(0); if (ty->u.f.proto != NULL && ty->u.f.proto[0] != NULL) { int i; for (i = 0; ty->u.f.proto[i] != NULL; i++) Seq_addhi(formals, to_generic_int(typeuid(ty->u.f.proto[i]))); } else if (ty->u.f.proto != NULL && ty->u.f.proto[0] == NULL) Seq_addhi(formals, to_generic_int(typeuid(voidtype))); type = rcc_FUNCTION(ty->size, ty->align, typeuid(ty->type), formals); break; } default: assert(0); } Seq_addhi(pickle->items, rcc_Type(ty->x.typeno, type)); return ty->x.typeno; }
/* * 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; }
/* 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 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; } }
/* Umsections_new makes a new 'assembler' in the form of a Umsections_T. It * creates a new table and makes the first key value pair with the given * section. It also sets the assembler to emit to that section. */ Umsections_T Umsections_new(const char *section, int (*error)(void *errstate, const char *message), void *errstate) { Umsections_T assembler = malloc(sizeof(*assembler)); assert(assembler); Table_T table = Table_new(100, NULL, NULL); assert(table); Seq_T order = Seq_new(100); assert(order); Seq_addhi(order, (void *)section); Seq_T instructions = Seq_new(100); assert(instructions); Table_put(table, Atom_string(section), instructions); /* intializes the struct */ assembler->table = table; assembler->section = section; assembler->order = order; assembler->err_func = error; assembler->errstate = errstate; return assembler; }
/* * 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); }
void test_add(Seq_T segments) { Segment s; NEW (s); s->length = SEG_LENGTH; s->data = Seq_new(SEG_LENGTH); for (unsigned i = 0; i < s->length; i++) { uint32_t *word = malloc(sizeof(uint32_t)); *word = i; Seq_addhi(s->data, word); } add_seg(SEG_LENGTH, s); Segment test = Seq_get(segments, SEG_LENGTH); for (unsigned i = 0; i < test->length; i++) { uint32_t *word = Seq_get(test->data, i); if (*word != i) printf("ADD IS A FAIL!!!!!\n"); } printf("ADD IS A SUCCESS!!!\n"); }
static void dopending(Symbol p) { if (pending != NULL) { int uid = symboluid(pending); rcc_symbol_ty symbol = mk_symbol(pending); Seq_addhi(pickle->items, rcc_Symbol(uid, symbol)); } pending = p; }
T Segmem_new_seg(int num_words, T segmem) { int *segment = malloc(num_words * sizeof(int)); // printf("%p \n", (void *)segment); Seq_addhi(segmem->memory, segment); segmem->length += 1; return segmem; }
/* 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; }
T Seq_seq(void *x, ...) { va_list ap; T seq = Seq_new(0); va_start(ap, x); for ( ; x; x = va_arg(ap, void *)) Seq_addhi(seq, x); va_end(ap); return seq; }
T Segmem_new(int num_words) { T segmem = malloc(sizeof(*segmem)); segmem->memory = Seq_new(1); segmem->length = 0; int *segment = malloc(num_words * sizeof(int)); Seq_addhi(segmem->memory, segment); return segmem; }
/* * create a segment with the size of nums, and return the index of the segs of * the mapped segment. There are two conditons, if the unmapped stack is not * empty, we reuse the segment index stored in unmapped stack and pop that out. * otherwise we just create a new segments and addhi into segs, the return index * is the length of segs. */ uint32_t map_segment(Mem myMem, uint32_t nums) { assert(myMem != NULL); Segment_T newSeg = Seg_new(nums); for (uint32_t i = 0; i < nums; i++) { Seq_addhi((Seq_T)newSeg, (void*) (uintptr_t) 0); } uint32_t index; if (Stack_empty(myMem->unmapped) == 1) { Seq_addhi(myMem->segs, (void*) newSeg); index = Seq_length(myMem->segs) - 1; } else { index = (int) (uintptr_t) Stack_pop(myMem->unmapped); Seg_free(Seq_put(myMem->segs, index, (void*) newSeg)); }; return index; }
/* * an existing segment of the given ID is unmapped, and the id of the * unmapped segment is stored for later use. */ extern void segMem_unmap(segment_data* segments, Seq_T freed_mem, uint32_t* regs, int rc_id){ segment_data toFree_struct = segments[regs[rc_id]]; free(toFree_struct->segment); free(toFree_struct); uint32_t* curr_id = malloc(sizeof(uint32_t)); *curr_id = regs[rc_id]; Seq_addhi(freed_mem, curr_id); segments[regs[rc_id]] = NULL; }
__declspec(dllexport) char* curl_shim_add_string(void* p, char* pInStr) { char* pOutStr; Seq_T seq = (Seq_T)p; pOutStr = (char*)malloc(strlen(pInStr) + 1); strcpy(pOutStr, pInStr); Seq_addhi(seq, pOutStr); return pOutStr; }
static void asdl_progbeg(int argc, char *argv[]) { int i; #if WIN32 _setmode(_fileno(stdout), _O_BINARY); #endif pickle = rcc_program(1, 0, Seq_new(0), Seq_new(0), argc, Seq_new(0)); for (i = 0; i < argc; i++) Seq_addhi(pickle->argv, to_generic_string(Text_box(argv[i], strlen(argv[i]) + 1))); interfaces = pickle->interfaces; }
/* UNMAP_SEGMENT * Input: Three ints (A, B, C) representing registers * * This function returns the segment found in the segment * memory sequence at the id found in register C. A NULL * character is placed at that space in the segment_memory * and that id is placed in the unmapped id sequence. * * Output: N/A */ void unmap_segment(int A, int B, int C) { // fprintf(stderr, "in unmap seg\n"); (void) A; (void) B; uint32_t c = register_at(C); Seg_array seg_array = SEG_MEMORY[c]; SEG_MEMORY[c] = 0; FREE(seg_array->segment); FREE(seg_array); Seq_addhi(UNMAP_SEG, (void *)(uintptr_t)c); }
static void asdl_function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { list_ty codelist = Seq_new(0), save, calleelist = Seq_new(0), callerlist = Seq_new(0); int i; dopending(f); for (i = 0; caller[i] != NULL; i++) { asdl_local(caller[i]); Seq_addhi(callerlist, to_generic_int(symboluid(caller[i]))); } for (i = 0; callee[i] != NULL; i++) { asdl_local(callee[i]); Seq_addhi(calleelist, to_generic_int(symboluid(callee[i]))); } save = interfaces; interfaces = codelist; gencode(caller, callee); asdl_segment(CODE); emitcode(); interfaces = save; put(rcc_Function(symboluid(f), callerlist, calleelist, ncalls, codelist)); }
/* * 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); }
static Node asdl_gen(Node p) { Node q; list_ty forest = Seq_new(0); for (q = p; p != NULL; p = p->link) if (specific(p->op) == JUMP+V && specific(p->kids[0]->op) == ADDRG+P && p->kids[0]->syms[0]->scope == LABELS) { p->syms[0] = p->kids[0]->syms[0]; p->kids[0] = NULL; } for (p = q; p != NULL; p = p->link) Seq_addhi(forest, visit(p)); put(rcc_Forest(forest)); temps = NULL; return q; }
/* Takes a file pointer to store the program at segment 0 and returns the newly * created segmented memory. */ T Segment_new() { WORD_SIZE i; T seg_mem = malloc(sizeof(struct Segment_T)); assert(seg_mem != NULL); Seq_T ids = Seq_new(MAP_INCREMENT); Seq_T segments = Seq_new(MAP_INCREMENT); for (i = 0; i < MAP_INCREMENT; i++) { Seq_addhi(ids, (void *)(uintptr_t)i); } seg_mem->unmapped_ids = ids; seg_mem->segments = segments; return seg_mem; }
/* returns a Segment array containing segments - hint must be >= 1 */ Segment Segments_new(int hint) { Seq_T outer = NULL; TRY outer = Seq_new(hint); assert(outer); for (int i = 0; i < hint; i++) { UArray_T inner = UArray_new(0, sizeof(uint32_t)); assert(inner); Seq_addhi(outer, inner); } EXCEPT (Mem_Failed) return NULL; END_TRY; return outer; }
/* 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())); }
/* creates/allocates space for a new segment in the overall Segments */ bool create_segment(Segment s, uint32_t length) { TRY UArray_T inner = UArray_new(length, sizeof(uint32_t)); if (inner == NULL) { return false; } for (int i = 0; i < (int) length; i++) { uint32_t *wordptr = UArray_at(inner, i); *wordptr = 0; } Seq_addhi(s, inner); EXCEPT (Mem_Failed) return false; END_TRY; return true; }
/* * Input: Mem_T structure, unsigned integer * Output: void * Purpose: Unmaps a segment from memory at the given segment index and frees * all memory associated with it. */ void unmap_segment(Mem_T memory, unsigned segIndex) { Seq_T unmapped_segment = Seq_put(memory->segment_seq, segIndex, NULL); Seq_free(&unmapped_segment); Seq_addhi(memory->reusable_indices, (void *)(intptr_t)segIndex); }
static void put(rcc_interface_ty node) { Seq_addhi(interfaces, node); }
int main(int argc, char *argv[]) { int c; sp = Seq_new(0); Fmt_register('D', MP_fmt); Fmt_register('U', MP_fmtu); while ((c = getchar()) != EOF) { MP_T x = NULL, y = NULL, z = NULL; TRY switch (c) { default: if (isprint(c)) Fmt_fprint(stderr, "?'%c'", c); else Fmt_fprint(stderr, "?'\\%03o'", c); Fmt_fprint(stderr, " is unimplemented\n"); break; case ' ': case '\t': case '\n': case '\f': case '\r': break; case 'c': while (Seq_length(sp) > 0) { MP_T x = Seq_remhi(sp); FREE(x); } break; case 'q': while (Seq_length(sp) > 0) { MP_T x = Seq_remhi(sp); FREE(x); } Seq_free(&sp); return EXIT_SUCCESS; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { char buf[512]; z = MP_new(0); { int i = 0; for ( ; strchr(&"zyxwvutsrqponmlkjihgfedcba9876543210"[36-ibase], tolower(c)); c = getchar(), i++) if (i < (int)sizeof (buf) - 1) buf[i] = c; if (i > (int)sizeof (buf) - 1) { i = (int)sizeof (buf) - 1; Fmt_fprint(stderr, "?integer constant exceeds %d digits\n", i); } buf[i] = '\0'; if (c != EOF) ungetc(c, stdin); } MP_fromstr(z, buf, ibase, NULL); break; } case '+': y = pop(); x = pop(); z = MP_new(0); (*f->add)(z, x, y); break; case '-': y = pop(); x = pop(); z = MP_new(0); (*f->sub)(z, x, y); break; case '*': y = pop(); x = pop(); z = MP_new(0); (*f->mul)(z, x, y); break; case '/': y = pop(); x = pop(); z = MP_new(0); (*f->div)(z, x, y); break; case '%': y = pop(); x = pop(); z = MP_new(0); (*f->mod)(z, x, y); break; case '&': y = pop(); x = pop(); z = MP_new(0); MP_and(z, x, y); break; case '|': y = pop(); x = pop(); z = MP_new(0); MP_or (z, x, y); break; case '^': y = pop(); x = pop(); z = MP_new(0); MP_xor(z, x, y); break; case '!': z = pop(); MP_not(z, z); break; case '~': z = pop(); MP_neg(z, z); break; case 'i': case 'o': { long n; x = pop(); n = MP_toint(x); if (n < 2 || n > 36) Fmt_fprint(stderr, "?%d is an illegal base\n",n); else if (c == 'i') ibase = n; else obase = n; if (obase == 2 || obase == 8 || obase == 16) f = &u; else f = &s; break; } case 'p': Fmt_print(f->fmt, z = pop(), obase); break; case 'f': { int n = Seq_length(sp); while (--n > 0) Fmt_print(f->fmt, Seq_get(sp, n), obase); break; } case '<': { long s; y = pop(); z = pop(); s = MP_toint(y); if (s < 0 || s > INT_MAX) { Fmt_fprint(stderr, "?%d is an illegal shift amount\n", s); break; }; MP_lshift(z, z, s); break; } case '>': { long s; y = pop(); z = pop(); s = MP_toint(y); if (s < 0 || s > INT_MAX) { Fmt_fprint(stderr, "?%d is an illegal shift amount\n", s); break; }; MP_rshift(z, z, s); break; } case 'k': { long n; x = pop(); n = MP_toint(x); if (n < 2 || n > INT_MAX) Fmt_fprint(stderr, "?%d is an illegal precision\n", n); else if (Seq_length(sp) > 0) Fmt_fprint(stderr, "?nonempty stack\n"); else MP_set(n); break; } case 'd': { MP_T x = pop(); z = MP_new(0); Seq_addhi(sp, x); MP_addui(z, x, 0); break; } } EXCEPT(MP_Overflow) Fmt_fprint(stderr, "?overflow\n"); EXCEPT(MP_Dividebyzero) Fmt_fprint(stderr, "?divide by 0\n"); END_TRY; if (z) Seq_addhi(sp, z); FREE(x); FREE(y); } while (Seq_length(sp) > 0) { MP_T x = Seq_remhi(sp); FREE(x); } Seq_free(&sp); return EXIT_SUCCESS; }
/* make Seq_T into a stack of integers */ static void push(Seq_T values, Um_word word) { assert(sizeof(Um_word) <= sizeof(uintptr_t)); Seq_addhi(values, (void *)(uintptr_t) word); }
static inline void emit(Seq_T stream, Um_instruction inst) { assert(sizeof(inst) <= sizeof(uintptr_t)); Seq_addhi(stream, (void *)(uintptr_t) inst); }