//deletes a statement and all of its pointers void stmt_delete(struct stmt *s){ if(!s) return; decl_delete(s->decl); expr_delete(s->init_expr); expr_delete(s->expr); expr_delete(s->next_expr); stmt_delete(s->body); stmt_delete(s->else_body); free(s); }
void expr_delete( struct expr *e ) { /* Careful: Stop on null pointer. */ if(!e) return; expr_delete(e->next); expr_delete(e->left); expr_delete(e->right); if (e->name) free(e->name); if (e->string_literal) free(e->string_literal); free ( e ); }
void decl_delete( struct decl *d ) { if (!d) return; free( d-> name ); type_delete( d->type ); expr_delete( d->value ); stmt_delete( d->code ); decl_delete( d->next ); free( d ); }
void expr_delete(struct expr* e) { // Handle the expression components. switch (e->type) { case EXPR_NUMBER: // Don't need to free any children components. break; case EXPR_LABEL: // Need to free the bstring. bdestroy((bstring)e->data); break; case EXPR_EXPR: // Need to free each child expression recursively. expr_delete(e->a); expr_delete(e->b); break; } // Free the expression itself. free(e); }
static void destructor(stmt_ty *sp) { stmt_command_ty *this; trace(("destructor(sp = %08X)\n{\n", sp)); /* assert(sp); */ /* assert(sp->method == &method); */ this = (stmt_command_ty *)sp; expr_list_destructor(&this->args); expr_list_destructor(&this->flags); if (this->input) expr_delete(this->input); expr_position_destructor(&this->pos); trace(("}\n")); }
//recursively delete an expression tree void expr_delete(struct expr *e){ if(!e) return; expr_delete(e->left); expr_delete(e->right); free(e); }
uint16_t aout_write(FILE* out, bool relocatable, bool intermediate) { struct aout_byte* current_outer; struct aout_byte* current_inner; struct lprov_entry* linker_provided = NULL; struct lprov_entry* linker_required = NULL; struct lprov_entry* linker_adjustment = NULL; struct lprov_entry* linker_section = NULL; struct lprov_entry* linker_output = NULL; struct lprov_entry* linker_temp = NULL; uint32_t mem_index, out_index; uint16_t inst; BFILE* temp = NULL; bstring bname, ename; uint16_t eaddr; bool did_find; bool shown_expr_warning = false; bool has_output = false; // Initialize out our extension table. code_offset += textn_init(start); // If relocatable, initialize out our relocation table. if (relocatable) code_offset += treloc_init(start); // First go through and evaluate all expressions that need to be. current_outer = start; out_index = code_offset; while (current_outer != NULL) { if (current_outer->type == AOUT_TYPE_METADATA_ORIGIN) { // Adjust memory address. out_index = current_outer->opcode; } else if (current_outer->type == AOUT_TYPE_METADATA_SECTION) { assert(current_outer->label != NULL); // We're exporting the current address as the beginning // of a section. if (!intermediate) ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL); // Check to make sure outputs haven't previously been emitted. if (has_output) ahalt(ERR_OUTPUT_BEFORE_SECTION, NULL); // Create linker entry. linker_temp = lprov_create(current_outer->label, out_index); linker_temp->next = linker_section; linker_section = linker_temp; printd(LEVEL_VERBOSE, "LINK SECTION %s -> 0x%04X\n", current_outer->label, out_index); } else if (current_outer->type == AOUT_TYPE_METADATA_OUTPUT) { assert(current_outer->label != NULL); // We're exporting the current address as the beginning // of a section. if (!intermediate) ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL); // Create linker entry. has_output = true; linker_temp = lprov_create(current_outer->label, out_index); linker_temp->next = linker_output; linker_output = linker_temp; printd(LEVEL_VERBOSE, "LINK OUTPUT 0x%04X -> %s\n", out_index, current_outer->label); } else if (current_outer->type == AOUT_TYPE_METADATA_EXPORT) { assert(current_outer->label != NULL); // We're exporting the address of this label in the // object table. if (!intermediate) ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL); // Resolve label position. ename = bfromcstr(current_outer->label); eaddr = aout_get_label_address(ename); bdestroy(ename); // Create linker entry. linker_temp = lprov_create(current_outer->label, eaddr); linker_temp->next = linker_provided; linker_provided = linker_temp; printd(LEVEL_VERBOSE, "LINK REPLACE %s -> 0x%04X\n", current_outer->label, eaddr); } else if (current_outer->type == AOUT_TYPE_NORMAL && current_outer->expr != NULL) { if (current_outer->expr->type != EXPR_LABEL) { // This is either just a number or a more complicated expression, so // evaluate it using the preprocessor expression engine. if ((relocatable || intermediate) && !shown_expr_warning) { printd(LEVEL_WARNING, "warning: expressions will not be adjusted at link or relocation time.\n"); printd(LEVEL_WARNING, " ensure labels are not used as part of expressions.\n"); shown_expr_warning = true; } current_outer->raw_used = true; current_outer->raw = expr_evaluate(current_outer->expr, &aout_get_label_address, &ahalt_expression_exit_handler); expr_delete(current_outer->expr); current_outer->expr = NULL; } else { // If this is just a label, we can handle it directly (this allows // us to handle imported labels in intermediate code). current_inner = start; mem_index = code_offset; did_find = false; // Search for .IMPORT directives first. while (current_inner != NULL) { if (current_inner->type == AOUT_TYPE_METADATA_ORIGIN) { // Adjust memory address. mem_index = current_inner->opcode; } else if (current_inner->type == AOUT_TYPE_METADATA_IMPORT) { // An imported label (we don't need to adjust // memory index because the existance of this type // of entry doesn't affect executable size). if (!intermediate) ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL); assert(current_outer->expr->data != NULL); if (strcmp(current_inner->label, ((bstring)current_outer->expr->data)->data) == 0) { // We don't actually know our position yet; // that will be handled by the linker! current_outer->raw = 0xFFFF; expr_delete(current_outer->expr); current_outer->expr = NULL; linker_temp = lprov_create(current_inner->label, out_index); linker_temp->next = linker_required; linker_required = linker_temp; printd(LEVEL_VERBOSE, "LINK REPLACE 0x%04X -> %s\n", out_index, current_inner->label); did_find = true; break; } } // Goto next. current_inner = current_inner->next; } // If it wasn't found in the .IMPORT directives, try searching // labels directly using the expression engine. if (!did_find) { // Replace the label position. current_outer->raw_used = true; current_outer->raw = expr_evaluate(current_outer->expr, &aout_get_label_address, &ahalt_expression_exit_handler); expr_delete(current_outer->expr); current_outer->expr = NULL; did_find = true; // We also need to add this entry to the adjustment // table for the linker since it also needs to adjust // internal label jumps in files when it concatenates // all of the object code together. linker_temp = lprov_create(NULL, out_index); linker_temp->next = linker_adjustment; linker_adjustment = linker_temp; printd(LEVEL_VERBOSE, "LINK ADJUST 0x%04X\n", out_index); } } } if (current_outer->type == AOUT_TYPE_NORMAL && current_outer->label == NULL) out_index += 1; current_outer = current_outer->next; } // If intermediate, we need to write out our linker table // as the absolute first thing in the file. if (intermediate) { fwrite(ldata_objfmt, 1, strlen(ldata_objfmt) + 1, out); objfile_save(out, linker_provided, linker_required, linker_adjustment, linker_section, linker_output); // Adjust the "true origin" for .ORIGIN directivies because // the linker table won't exist in the final result when // linked. true_origin = (uint16_t)ftell(out); } // Write out our extension table. textn_write(out); // If relocatable, write out our relocation table. if (relocatable) treloc_write(out); // Now write to the file. current_outer = start; while (current_outer != NULL) { if (current_outer->type == AOUT_TYPE_METADATA_ORIGIN) { // Adjust origin. fseek(out, true_origin + current_outer->opcode * 2 /* double because the number is in words, not bytes */, SEEK_SET); } else if (current_outer->type == AOUT_TYPE_METADATA_INCBIN) { // Include binary file. bname = ppfind_locate(bautofree(bfromcstr(current_outer->label))); if (bname == NULL) ahalt(ERR_UNABLE_TO_INCBIN, current_outer->label); temp = bfopen((const char*)(bname->data), "rb"); if (temp == NULL) ahalt(ERR_UNABLE_TO_INCBIN, current_outer->label); // Copy binary data. while (!bfeof(temp)) { // TODO: This could be faster if we didn't do it character // by character. fputc(bfgetc(temp), out); } // Finalize. bfclose(temp); bdestroy(bname); } else if (current_outer->type == AOUT_TYPE_NORMAL) { // Update the debugging symbol. dbgfmt_update_symbol_list(¤t_outer->symbols, (uint16_t)((ftell(out) - true_origin) / 2)); // Normal output. if (current_outer->raw_used == true) { inst = current_outer->raw; iwrite(&inst, out); } else if (current_outer->label == NULL) { inst = INSTRUCTION_CREATE(current_outer->opcode, current_outer->a, current_outer->b); iwrite(&inst, out); } } // Goto next in linked list. current_outer = current_outer->next; } fflush(out); return (uint16_t)((ftell(out) - true_origin) / 2); }