static int add_expoint_address_resolve(int resolve_type, int ep_index) { #ifdef SANITY_CHECK if (resolve_type != ADDRESS_RESOLVE_LABEL // this type doesn't use exit points; ep_index is the label identifier or something (stupidly) && (ep_index < 0 || ep_index >= EXPOINTS)) { fpr("\nError: c_generate.c: add_expoint_address_resolve(): invalid exit point index %i at intercode %i (source line %i)", ep_index, cstate.ic_pos, cstate.intercode[cstate.ic_pos].src_line); error_call(); } #endif if (cstate.resolve_pos >= ADDRESS_RESOLUTION_ENTRIES - 1) return intercode_error_text("too many addresses to resolve"); // shouldn't realistically happen cstate.ic_address_resolution[cstate.resolve_pos].type = resolve_type; cstate.ic_address_resolution[cstate.resolve_pos].bcode_pos = cstate.bc_pos; cstate.ic_address_resolution[cstate.resolve_pos].value = ep_index; cstate.resolve_pos++; cstate.target_bcode->src_line[cstate.bc_pos] = cstate.intercode[cstate.ic_pos].src_line; cstate.bc_pos ++; // this bcode entry is ignored for now, but will be fixed later by resolve_addresses() return 1; }
void Module::genhelpers(bool iscomdat) { // If module assert for (int i = 0; i < 3; i++) { Symbol *ma; unsigned rt; unsigned bc; switch (i) { case 0: ma = marray; rt = RTLSYM_DARRAY; bc = BCexit; break; case 1: ma = massert; rt = RTLSYM_DASSERT; bc = BCexit; break; case 2: ma = munittest; rt = RTLSYM_DUNITTEST; bc = BCret; break; default: assert(0); } if (ma) { elem *elinnum; localgot = NULL; // Call dassert(filename, line) // Get sole parameter, linnum { Symbol *sp = symbol_calloc("linnum"); sp->Stype = type_fake(TYint); sp->Stype->Tcount++; sp->Sclass = (config.exe == EX_WIN64) ? SCshadowreg : SCfastpar; FuncParamRegs fpr(TYjfunc); fpr.alloc(sp->Stype, sp->Stype->Tty, &sp->Spreg, &sp->Spreg2); sp->Sflags &= ~SFLspill; sp->Sfl = (sp->Sclass == SCshadowreg) ? FLpara : FLfast; cstate.CSpsymtab = &ma->Sfunc->Flocsym; symbol_add(sp); elinnum = el_var(sp); } elem *efilename = toEfilename(this); elem *e = el_var(rtlsym[rt]); e = el_bin(OPcall, TYvoid, e, el_param(elinnum, efilename)); block *b = block_calloc(); b->BC = bc; b->Belem = e; ma->Sfunc->Fstartline.Sfilename = arg; ma->Sfunc->Fstartblock = b; ma->Sclass = iscomdat ? SCcomdat : SCglobal; ma->Sfl = 0; ma->Sflags |= rtlsym[rt]->Sflags & SFLexit; writefunc(ma); } } }
static void genhelpers(Module *m) { // If module assert for (int i = 0; i < 3; i++) { Symbol *ma; unsigned rt; unsigned bc; switch (i) { case 0: ma = toModuleArray(m); rt = RTLSYM_DARRAY; bc = BCexit; break; case 1: ma = toModuleAssert(m); rt = RTLSYM_DASSERT; bc = BCexit; break; case 2: ma = toModuleUnittest(m); rt = RTLSYM_DUNITTEST; bc = BCret; break; default: assert(0); } if (!ma) continue; localgot = NULL; // Call dassert(filename, line) // Get sole parameter, linnum Symbol *sp = symbol_calloc("linnum"); sp->Stype = type_fake(TYint); sp->Stype->Tcount++; sp->Sclass = (config.exe == EX_WIN64) ? SCshadowreg : SCfastpar; FuncParamRegs fpr(TYjfunc); fpr.alloc(sp->Stype, sp->Stype->Tty, &sp->Spreg, &sp->Spreg2); sp->Sflags &= ~SFLspill; sp->Sfl = (sp->Sclass == SCshadowreg) ? FLpara : FLfast; cstate.CSpsymtab = &ma->Sfunc->Flocsym; symbol_add(sp); elem *elinnum = el_var(sp); elem *efilename = toEfilename(m); if (config.exe == EX_WIN64) efilename = addressElem(efilename, Type::tstring, true); elem *e = el_var(getRtlsym(rt)); e = el_bin(OPcall, TYvoid, e, el_param(elinnum, efilename)); block *b = block_calloc(); b->BC = bc; b->Belem = e; ma->Sfunc->Fstartline.Sfilename = m->arg; ma->Sfunc->Fstartblock = b; ma->Sclass = SCglobal; ma->Sfl = 0; ma->Sflags |= getRtlsym(rt)->Sflags & SFLexit; writefunc(ma); } }
// call this function when a template has been finished and is ready to be put in the game. // it reads the classes that each object has been assigned to (in the objects' object_class arrays) // and uses that to build the class lists in the main template struct. // - can be called from code and design int finalise_template_class_lists(void) { int i, j, k, m, class_index; char error_text [60]; // may as well start by clearing the lists: for (i = 0; i < OBJECT_CLASSES; i ++) { for (j = 0; j < OBJECT_CLASS_SIZE; j ++) { fstate.target_templ->object_class_member [i] [j] = -1; fstate.target_templ->object_class_object [i] [j] = -1; } } // now go through each member, object, and object object_class for (i = 0; i < GROUP_MAX_MEMBERS; i ++) { if (fstate.target_templ->member[i].exists == 0) continue; for (j = 0; j < MAX_OBJECTS; j ++) { if (fstate.target_templ->member[i].object[j].type == OBJECT_TYPE_NONE) continue; for (k = 0; k < CLASSES_PER_OBJECT; k ++) { if (fstate.target_templ->member[i].object[j].object_class [k] == -1) continue; class_index = fstate.target_templ->member[i].object[j].object_class [k]; #ifdef SANITY_CHECK if (class_index < 0 || class_index >= OBJECT_CLASSES) { fpr("\nError: c_fix.c:finalise_template_class_lists(): invalid class_index %i for member %i object %i object_class %i", class_index, i, j, k); error_call(); } #endif for (m = 0; m < OBJECT_CLASS_SIZE; m ++) { if (fstate.target_templ->object_class_member [class_index] [m] == -1) break; } if (m == OBJECT_CLASS_SIZE) { snprintf(error_text, 60, "object class %s has too many objects (maximum is %i)", fstate.target_templ->object_class_name [class_index], OBJECT_CLASS_SIZE); return comp_error_text(error_text, NULL); } fstate.target_templ->object_class_active [class_index] = 1; // shouldn't be needed but can't hurt fstate.target_templ->object_class_member [class_index] [m] = i; fstate.target_templ->object_class_object [class_index] [m] = j; } } } return 1; }
void ValueRep::emitRestore(AssemblyHelpers& jit, Reg reg) const { if (reg.isGPR()) { switch (kind()) { case LateRegister: case Register: if (isGPR()) jit.move(gpr(), reg.gpr()); else jit.moveDoubleTo64(fpr(), reg.gpr()); break; case Stack: jit.load64(AssemblyHelpers::Address(GPRInfo::callFrameRegister, offsetFromFP()), reg.gpr()); break; case Constant: jit.move(AssemblyHelpers::TrustedImm64(value()), reg.gpr()); break; default: RELEASE_ASSERT_NOT_REACHED(); break; } return; } switch (kind()) { case LateRegister: case Register: if (isGPR()) jit.move64ToDouble(gpr(), reg.fpr()); else jit.moveDouble(fpr(), reg.fpr()); break; case Stack: jit.loadDouble(AssemblyHelpers::Address(GPRInfo::callFrameRegister, offsetFromFP()), reg.fpr()); break; case Constant: jit.move(AssemblyHelpers::TrustedImm64(value()), jit.scratchRegister()); jit.move64ToDouble(jit.scratchRegister(), reg.fpr()); break; default: RELEASE_ASSERT_NOT_REACHED(); break; } }
void VariableEvent::dumpFillInfo(const char* name, PrintStream& out) const { out.print(name, "(", id(), ", "); if (dataFormat() == DataFormatDouble) out.printf("%s", FPRInfo::debugName(fpr())); #if USE(JSVALUE32_64) else if (dataFormat() & DataFormatJS) out.printf("%s:%s", GPRInfo::debugName(tagGPR()), GPRInfo::debugName(payloadGPR())); #endif else out.printf("%s", GPRInfo::debugName(gpr())); out.printf(", %s)", dataFormatToString(dataFormat())); }
// Call this to set a player's spawn position to near the latest well in the map_init structure, // and a particular angle from that well. // Is called from s_mission.c (from which map_init may not be accessible - not sure) void set_player_spawn_position_by_latest_well(int player_index, int angle_from_well, int distance_from_well) { #ifdef SANITY_CHECK if (map_init.data_wells <= 0) { fpr("\n Error: g_world_map.c: set_player_spawn_position_by_latest_well(): no wells yet."); error_call(); } #endif set_player_spawn_position_by_specified_well(player_index, map_init.data_wells - 1, angle_from_well, distance_from_well); }
void approx_poly ( ElFifo<INT> & res, const ElFifo<Pt2di> & fpi, ArgAPP arg ) { ElFifo<Pt2dr> fpr(fpi.size(),fpi.circ());; for (INT aK=0 ; aK<INT(fpi.size()) ; aK++) fpr.push_back(Pt2dr(fpi[aK])); approx_poly(res,fpr,arg); }
void init_waveform(float* buffer, int buffer_length) { if (buffer_length > SYNTH_SAMPLE_MAX_SIZE) { fpr("\n Error: x_synth.c: init_waveform(): buffer too large (%i)", buffer_length); error_call(); } int i; for (i = 0; i < buffer_length; i ++) { buffer [i] = 0; } }
void safe_exit(int exit_value) { fprintf(stdout, "\nStopping sound thread."); stop_sound_thread(); // will only stop the sound thread if it's been initialised fprintf(stdout, "\nDestroying display."); if (display != NULL) // display is initialised to NULL right at the start al_destroy_display(display); fprintf(stdout, "\nDestroying timer."); if (timer != NULL) // same al_destroy_timer(timer); fpr("\nClosing down Allegro system."); al_uninstall_system(); fprintf(stdout, "\nExiting with value %i.", exit_value); exit(exit_value); }
void add_extra_spawn_by_latest_well(int player_index, int template_index, int angle_from_well) { #ifdef SANITY_CHECK if (map_init.data_wells <= 0) { fpr("\n Error: g_world_map.c: set_player_spawn_position_by_latest_well(): no wells yet."); error_call(); } #endif int well_index = map_init.data_wells - 1; al_fixed well_x = block_to_fixed(map_init.data_well_position[well_index].x) + BLOCK_SIZE_FIXED / 2; al_fixed well_y = block_to_fixed(map_init.data_well_position[well_index].y) + BLOCK_SIZE_FIXED / 2; int spawn_block_x = fixed_to_block(well_x + fixed_xpart(int_angle_to_fixed(angle_from_well), al_itofix(512))); int spawn_block_y = fixed_to_block(well_y + fixed_ypart(int_angle_to_fixed(angle_from_well), al_itofix(512))); add_extra_spawn(player_index, template_index, spawn_block_x, spawn_block_y, angle_from_well); }
// returns number of data well just placed, in case it's useful int add_data_well_to_map_init(int x, int y, int reserve_A, int reserve_B, int reserve_squares, float spin_rate) { #ifdef SANITY_CHECK if (map_init.data_wells >= DATA_WELLS) { fpr("\nError: s_mission.c: add_data_well_to_map_init(): too many data wells"); error_call(); } #endif map_init.data_well_position [map_init.data_wells].x = x; map_init.data_well_position [map_init.data_wells].y = y; map_init.data_well_reserve_data [map_init.data_wells] [0] = reserve_A; map_init.data_well_reserve_data [map_init.data_wells] [1] = reserve_B; map_init.data_well_reserve_squares [map_init.data_wells] = reserve_squares; map_init.data_well_spin_rate [map_init.data_wells] = spin_rate; map_init.data_wells ++; return map_init.data_wells - 1; }
// adds a data well to an mdetail ring at a particular angle. // returns the index of the data well. int add_data_well_to_mdetail_ring(int mdetail_ring_index, int angle, int reserve_A, int reserve_B, int reserve_squares, float spin_rate) { #ifdef SANITY_CHECK if (mdetail_ring_index < 0 || (map_init.mdetail[mdetail_ring_index].type != MDETAIL_RING && map_init.mdetail[mdetail_ring_index].type != MDETAIL_RING_EMPTY)) { fpr("\n g_world_map.c: add_data_well_to_mdetail_ring(): failed (ring_index %i)", mdetail_ring_index); } #endif al_fixed fixed_angle = int_angle_to_fixed(angle); int ring_size_pixels = (map_init.mdetail[mdetail_ring_index].dsize + 5) * BLOCK_SIZE_PIXELS; al_fixed well_x_fixed = block_to_fixed(map_init.mdetail[mdetail_ring_index].block_position.x) + fixed_xpart(fixed_angle, al_itofix(ring_size_pixels)); al_fixed well_y_fixed = block_to_fixed(map_init.mdetail[mdetail_ring_index].block_position.y) + fixed_ypart(fixed_angle, al_itofix(ring_size_pixels)); int well_x_block = fixed_to_block(well_x_fixed); int well_y_block = fixed_to_block(well_y_fixed); return add_data_well_to_map_init(well_x_block, well_y_block, reserve_A, reserve_B, reserve_squares, spin_rate); }
// returns number of next mdetail, or -1 if none left // - actually should probably be an error to use up all mdetails static int new_mdetail(int mdetail_type) { int i; for (i = 0; i < MDETAILS; i ++) { if (map_init.mdetail[i].type == MDETAIL_NONE) { map_init.mdetail[i].type = mdetail_type; return i; } } // no empty space in array #ifdef SANITY_CHECK fpr("\n Error: g_world_map.c: new_mdetail(): too many map details."); error_call(); #endif return -1; }
// standard paths not yet implemented void init_standard_paths(void) { settings.path_to_executable [0] = 0; if (settings.option [OPTION_STANDARD_PATHS] == STANDARD_PATHS_EXECUTABLE) { // Unfortunately there does not seem to be any simple way to find the execution directory. // We can only get the full path of the executable, including the file name. // So we need to remove the file name from the end of the path: ALLEGRO_PATH* executable_path; executable_path = al_get_standard_path(ALLEGRO_EXENAME_PATH); if (executable_path == NULL) { // may still be okay... fpr("\nFailed to get executable path. Attempting to run using relative paths..."); return; } char filename [100]; // 100 should be plenty of room strncpy(filename, al_get_path_filename(executable_path), 95); // 95 should too int filename_length = strlen(filename); // const char* temp_path = al_path_cstr(executable_path, ALLEGRO_NATIVE_PATH_SEP); // this pointer should be valid until the path is modified // int temp_path_length = strlen(temp_path); char file_path [FILE_PATH_LENGTH]; strncpy(file_path, al_path_cstr(executable_path, ALLEGRO_NATIVE_PATH_SEP), FILE_PATH_LENGTH - 5); int file_path_length = strlen(file_path); if (file_path_length >= FILE_PATH_LENGTH - 10) { fpr("\nSorry, your file path (%s) is too long (%i characters; the maximum is %i).", file_path, file_path_length, FILE_PATH_LENGTH - 10); fpr("\nAttempting to run using relative paths..."); return; } file_path [file_path_length - filename_length] = 0; strcpy(settings.path_to_executable, file_path); al_destroy_path(executable_path); return; } if (settings.option [OPTION_STANDARD_PATHS] == STANDARD_PATHS_VARIOUS) { /* ALLEGRO_PATH* standard_path; // PATH_TYPE_RESOURCES: standard_path = al_get_standard_path(ALLEGRO_RESOURCES_PATH); if (standard_path == NULL) // may still be okay... fpr("\nFailed to get resources path. Attempting to run using relative path..."); else { char temp_path [FILE_PATH_LENGTH]; strncpy(temp_path, al_path_cstr(standard_path, ALLEGRO_NATIVE_PATH_SEP), FILE_PATH_LENGTH - 10); int temp_path_length = strlen(temp_path); if (temp_path_length >= FILE_PATH_LENGTH - 20) { fpr("\nSorry, your resources path (%s) is too long (maximum %i).", temp_path, FILE_PATH_LENGTH - 20); fpr("\nAttempting to run using relative path..."); } else { strcpy(settings.standard_path [PATH_TYPE_RESOURCES], temp_path; } al_destroy_path(standard_path); } */ } // settings.option [OPTION_STANDARD_PATHS] is probably STANDARD_PATHS_NONE return; }
// call this for every member except the core static int procdef_read_member_recursively(void)//, int parent_connection_index) { // int child_member_index; struct ctokenstruct ctoken; // init_templ_group_member(fstate.target_templ, child_member_index); // expect open brace: if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_BRACE_OPEN)) return comp_error_text("expected open brace at start of process member", &ctoken); // read member's shape: // (check for core process shapees first because this is an obvious mistake to make) if (accept_next(&ctoken, CTOKEN_TYPE_IDENTIFIER_CORE_SHAPE, -1)) return comp_error_text("only the process core can be a core shape", &ctoken); if (!accept_next(&ctoken, CTOKEN_TYPE_IDENTIFIER_SHAPE, -1)) return comp_error_text("expected process shape", &ctoken); int component_shape = identifier[ctoken.identifier_index].value; write_to_procdef(component_shape); #ifdef TEST_PROCDEF fpr("\nwrite component_shape %i (%i)", component_shape, procdef.buffer_length); #endif // fstate.target_templ->member[child_member_index].shape = identifier[ctoken.identifier_index].value; // accept (but don't require) a comma: accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_COMMA); // could check for error here... // fstate.target_templ->member[child_member_index].exists = 1; // location etc can wait until later // fstate.target_templ->member[child_member_index].connection[0].template_member_index = parent_member_index; // fstate.target_templ->member[child_member_index].connection[0].reverse_link_index = parent_object; // fstate.target_templ->member[child_member_index].connection[0].reverse_connection_index = parent_connection_index; // the final part of the connection structure, link_index, will be filled in below after the member's uplink object is found // fstate.target_templ->member[parent_member_index].connection[parent_connection_index].template_member_index = child_member_index; // fstate.target_templ->member[parent_member_index].connection[parent_connection_index].link_index = parent_object; // fstate.target_templ->member[parent_member_index].connection[parent_connection_index].reverse_connection_index = 0; // reverse_link_index set below if (!procdef_read_member_objects_recursively(component_shape)) return 0; /* // now find the uplink: int i; int uplink_object_index = -1; for (i = 0; i < MAX_OBJECTS; i ++) { if (fstate.target_templ->member[child_member_index].object[i].type == OBJECT_TYPE_UPLINK) { if (uplink_object_index != -1) return comp_error_text("member process has more than one uplink object", NULL); uplink_object_index = i; } } fstate.target_templ->member[child_member_index].connection[0].link_index = uplink_object_index; fstate.target_templ->member[parent_member_index].connection[parent_connection_index].reverse_link_index = uplink_object_index; // The angle of the parent member's downlink object should be sufficient to work out where this member is: fstate.target_templ->member[child_member_index].connection_angle_offset_angle = fstate.target_templ->member[parent_member_index].object[parent_object].base_angle_offset_angle; fstate.target_templ->member[child_member_index].connection_angle_offset = int_angle_to_fixed(fstate.target_templ->member[child_member_index].connection_angle_offset_angle); */ if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_BRACE_CLOSE)) return comp_error_text("expected closing brace at end of process member (too many objects?)", &ctoken); //* not sure about these open/close braces return 1; }
void FuncDeclaration::toObjFile(int multiobj) { FuncDeclaration *func = this; ClassDeclaration *cd = func->parent->isClassDeclaration(); int reverse; int has_arguments; //printf("FuncDeclaration::toObjFile(%p, %s.%s)\n", func, parent->toChars(), func->toChars()); //if (type) printf("type = %s\n", func->type->toChars()); #if 0 //printf("line = %d\n",func->getWhere() / LINEINC); EEcontext *ee = env->getEEcontext(); if (ee->EEcompile == 2) { if (ee->EElinnum < (func->getWhere() / LINEINC) || ee->EElinnum > (func->endwhere / LINEINC) ) return; // don't compile this function ee->EEfunc = func->toSymbol(); } #endif if (semanticRun >= PASSobj) // if toObjFile() already run return; // If errors occurred compiling it, such as bugzilla 6118 if (type && type->ty == Tfunction && ((TypeFunction *)type)->next->ty == Terror) return; if (!func->fbody) { return; } if (func->isUnitTestDeclaration() && !global.params.useUnitTests) return; if (multiobj && !isStaticDtorDeclaration() && !isStaticCtorDeclaration()) { obj_append(this); return; } if (semanticRun == PASSsemanticdone) { /* What happened is this function failed semantic3() with errors, * but the errors were gagged. * Try to reproduce those errors, and then fail. */ error("errors compiling the function"); return; } assert(semanticRun == PASSsemantic3done); semanticRun = PASSobj; if (global.params.verbose) printf("function %s\n",func->toPrettyChars()); Symbol *s = func->toSymbol(); func_t *f = s->Sfunc; #if TARGET_WINDOS /* This is done so that the 'this' pointer on the stack is the same * distance away from the function parameters, so that an overriding * function can call the nested fdensure or fdrequire of its overridden function * and the stack offsets are the same. */ if (isVirtual() && (fensure || frequire)) f->Fflags3 |= Ffakeeh; #endif #if TARGET_OSX s->Sclass = SCcomdat; #else s->Sclass = SCglobal; #endif for (Dsymbol *p = parent; p; p = p->parent) { if (p->isTemplateInstance()) { s->Sclass = SCcomdat; break; } } /* Vector operations should be comdat's */ if (isArrayOp) s->Sclass = SCcomdat; if (isNested()) { // if (!(config.flags3 & CFG3pic)) // s->Sclass = SCstatic; f->Fflags3 |= Fnested; /* The enclosing function must have its code generated first, * so we know things like where its local symbols are stored. */ FuncDeclaration *fdp = toAliasFunc()->toParent2()->isFuncDeclaration(); // Bug 8016 - only include the function if it is a template instance Dsymbol * owner = NULL; if (fdp) { owner = fdp->toParent(); while (owner && !owner->isTemplateInstance()) owner = owner->toParent(); } if (owner && fdp && fdp->semanticRun == PASSsemantic3done && !fdp->isUnitTestDeclaration()) { /* Can't do unittest's out of order, they are order dependent in that their * execution is done in lexical order, and some modules (std.datetime *cough* * *cough*) rely on this. */ fdp->toObjFile(multiobj); } } else { const char *libname = (global.params.symdebug) ? global.params.debuglibname : global.params.defaultlibname; // Pull in RTL startup code (but only once) if (func->isMain() && onlyOneMain(loc)) { #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS objmod->external_def("_main"); objmod->ehsections(); // initialize exception handling sections #endif #if TARGET_WINDOS if (I64) { objmod->external_def("main"); objmod->ehsections(); // initialize exception handling sections } else { objmod->external_def("_main"); objmod->external_def("__acrtused_con"); } #endif objmod->includelib(libname); s->Sclass = SCglobal; } else if (strcmp(s->Sident, "main") == 0 && linkage == LINKc) { #if TARGET_WINDOS if (I64) { objmod->includelib("LIBCMT"); objmod->includelib("OLDNAMES"); } else { objmod->external_def("__acrtused_con"); // bring in C startup code objmod->includelib("snn.lib"); // bring in C runtime library } #endif s->Sclass = SCglobal; } #if TARGET_WINDOS else if (func->isWinMain() && onlyOneMain(loc)) { if (I64) { objmod->includelib("uuid"); objmod->includelib("LIBCMT"); objmod->includelib("OLDNAMES"); objmod->ehsections(); // initialize exception handling sections } else { objmod->external_def("__acrtused"); } objmod->includelib(libname); s->Sclass = SCglobal; } // Pull in RTL startup code else if (func->isDllMain() && onlyOneMain(loc)) { if (I64) { objmod->includelib("uuid"); objmod->includelib("LIBCMT"); objmod->includelib("OLDNAMES"); objmod->ehsections(); // initialize exception handling sections } else { objmod->external_def("__acrtused_dll"); } objmod->includelib(libname); s->Sclass = SCglobal; } #endif } cstate.CSpsymtab = &f->Flocsym; // Find module m for this function Module *m = NULL; for (Dsymbol *p = parent; p; p = p->parent) { m = p->isModule(); if (m) break; } IRState irs(m, func); Dsymbols deferToObj; // write these to OBJ file later irs.deferToObj = &deferToObj; TypeFunction *tf; enum RET retmethod; symbol *shidden = NULL; Symbol *sthis = NULL; tym_t tyf; tyf = tybasic(s->Stype->Tty); //printf("linkage = %d, tyf = x%x\n", linkage, tyf); reverse = tyrevfunc(s->Stype->Tty); assert(func->type->ty == Tfunction); tf = (TypeFunction *)(func->type); has_arguments = (tf->linkage == LINKd) && (tf->varargs == 1); retmethod = tf->retStyle(); if (retmethod == RETstack) { // If function returns a struct, put a pointer to that // as the first argument ::type *thidden = tf->next->pointerTo()->toCtype(); char hiddenparam[5+4+1]; static int hiddenparami; // how many we've generated so far sprintf(hiddenparam,"__HID%d",++hiddenparami); shidden = symbol_name(hiddenparam,SCparameter,thidden); shidden->Sflags |= SFLtrue | SFLfree; #if DMDV1 if (func->nrvo_can && func->nrvo_var && func->nrvo_var->nestedref) #else if (func->nrvo_can && func->nrvo_var && func->nrvo_var->nestedrefs.dim) #endif type_setcv(&shidden->Stype, shidden->Stype->Tty | mTYvolatile); irs.shidden = shidden; this->shidden = shidden; } else { // Register return style cannot make nrvo. // Auto functions keep the nrvo_can flag up to here, // so we should eliminate it before entering backend. nrvo_can = 0; } if (vthis) { assert(!vthis->csym); sthis = vthis->toSymbol(); irs.sthis = sthis; if (!(f->Fflags3 & Fnested)) f->Fflags3 |= Fmember; } Symbol **params; // Estimate number of parameters, pi size_t pi = (v_arguments != NULL); if (parameters) pi += parameters->dim; // Allow extra 2 for sthis and shidden params = (Symbol **)alloca((pi + 2) * sizeof(Symbol *)); // Get the actual number of parameters, pi, and fill in the params[] pi = 0; if (v_arguments) { params[pi] = v_arguments->toSymbol(); pi += 1; } if (parameters) { for (size_t i = 0; i < parameters->dim; i++) { VarDeclaration *v = (*parameters)[i]; if (v->csym) { error("compiler error, parameter '%s', bugzilla 2962?", v->toChars()); assert(0); } params[pi + i] = v->toSymbol(); } pi += parameters->dim; } if (reverse) { // Reverse params[] entries for (size_t i = 0; i < pi/2; i++) { Symbol *sptmp = params[i]; params[i] = params[pi - 1 - i]; params[pi - 1 - i] = sptmp; } } if (shidden) { #if 0 // shidden becomes last parameter params[pi] = shidden; #else // shidden becomes first parameter memmove(params + 1, params, pi * sizeof(params[0])); params[0] = shidden; #endif pi++; } if (sthis) { #if 0 // sthis becomes last parameter params[pi] = sthis; #else // sthis becomes first parameter memmove(params + 1, params, pi * sizeof(params[0])); params[0] = sthis; #endif pi++; } if ((global.params.isLinux || global.params.isOSX || global.params.isFreeBSD || global.params.isSolaris) && linkage != LINKd && shidden && sthis) { /* swap shidden and sthis */ Symbol *sp = params[0]; params[0] = params[1]; params[1] = sp; } for (size_t i = 0; i < pi; i++) { Symbol *sp = params[i]; sp->Sclass = SCparameter; sp->Sflags &= ~SFLspill; sp->Sfl = FLpara; symbol_add(sp); } // Determine register assignments if (pi) { FuncParamRegs fpr(tyf); for (size_t i = 0; i < pi; i++) { Symbol *sp = params[i]; if (fpr.alloc(sp->Stype, sp->Stype->Tty, &sp->Spreg, &sp->Spreg2)) { sp->Sclass = (config.exe == EX_WIN64) ? SCshadowreg : SCfastpar; sp->Sfl = (sp->Sclass == SCshadowreg) ? FLpara : FLfast; } } } if (func->fbody) { block *b; Blockx bx; localgot = NULL; Statement *sbody = func->fbody; memset(&bx,0,sizeof(bx)); bx.startblock = block_calloc(); bx.curblock = bx.startblock; bx.funcsym = s; bx.scope_index = -1; bx.classdec = cd; bx.member = func; bx.module = getModule(); irs.blx = &bx; /* If profiling, insert call to the profiler here. * _c_trace_pro(char* funcname); */ if (global.params.trace) { dt_t *dt = NULL; char *id = s->Sident; size_t len = strlen(id); dtnbytes(&dt, len + 1, id); Symbol *sfuncname = symbol_generate(SCstatic,type_fake(TYchar)); sfuncname->Sdt = dt; sfuncname->Sfl = FLdata; out_readonly(sfuncname); outdata(sfuncname); elem *efuncname = el_ptr(sfuncname); elem *eparam = el_params(efuncname, el_long(TYsize_t, len), NULL); elem *e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_TRACE_CPRO]), eparam); block_appendexp(bx.curblock, e); } #if DMDV2 buildClosure(&irs); #endif #if 0 if (func->isSynchronized()) { if (cd) { elem *esync; if (func->isStatic()) { // monitor is in ClassInfo esync = el_ptr(cd->toSymbol()); } else { // 'this' is the monitor esync = el_var(sthis); } if (func->isStatic() || sbody->usesEH() || !(config.flags2 & CFG2seh)) { // BUG: what if frequire or fensure uses EH? sbody = new SynchronizedStatement(func->loc, esync, sbody); } else { #if TARGET_WINDOS if (config.flags2 & CFG2seh) { /* The "jmonitor" uses an optimized exception handling frame * which is a little shorter than the more general EH frame. * It isn't strictly necessary. */ s->Sfunc->Fflags3 |= Fjmonitor; } #endif el_free(esync); } } else { error("synchronized function %s must be a member of a class", func->toChars()); } } #elif TARGET_WINDOS if (func->isSynchronized() && cd && config.flags2 & CFG2seh && !func->isStatic() && !sbody->usesEH()) { /* The "jmonitor" hack uses an optimized exception handling frame * which is a little shorter than the more general EH frame. */ s->Sfunc->Fflags3 |= Fjmonitor; } #endif sbody->toIR(&irs); bx.curblock->BC = BCret; f->Fstartblock = bx.startblock; // einit = el_combine(einit,bx.init); if (isCtorDeclaration()) { assert(sthis); for (b = f->Fstartblock; b; b = b->Bnext) { if (b->BC == BCret) { b->BC = BCretexp; b->Belem = el_combine(b->Belem, el_var(sthis)); } } } } // If static constructor #if DMDV2 if (isSharedStaticCtorDeclaration()) // must come first because it derives from StaticCtorDeclaration { ssharedctors.push(s); } else #endif if (isStaticCtorDeclaration()) { sctors.push(s); } // If static destructor #if DMDV2 if (isSharedStaticDtorDeclaration()) // must come first because it derives from StaticDtorDeclaration { SharedStaticDtorDeclaration *f = isSharedStaticDtorDeclaration(); assert(f); if (f->vgate) { /* Increment destructor's vgate at construction time */ esharedctorgates.push(f); } sshareddtors.shift(s); } else #endif if (isStaticDtorDeclaration()) { StaticDtorDeclaration *f = isStaticDtorDeclaration(); assert(f); if (f->vgate) { /* Increment destructor's vgate at construction time */ ectorgates.push(f); } sdtors.shift(s); } // If unit test if (isUnitTestDeclaration()) { stests.push(s); } if (global.errors) return; writefunc(s); if (isExport()) objmod->export_symbol(s, Para.offset); for (size_t i = 0; i < irs.deferToObj->dim; i++) { Dsymbol *s = (*irs.deferToObj)[i]; FuncDeclaration *fd = s->isFuncDeclaration(); if (fd) { FuncDeclaration *fdp = fd->toParent2()->isFuncDeclaration(); if (fdp && fdp->semanticRun < PASSobj) { /* Bugzilla 7595 * FuncDeclaration::buildClosure() relies on nested functions * being toObjFile'd after the outer function. Otherwise, the * v->offset's for the closure variables are wrong. * So, defer fd until after fdp is done. */ fdp->deferred.push(fd); continue; } } s->toObjFile(0); } for (size_t i = 0; i < deferred.dim; i++) { FuncDeclaration *fd = deferred[i]; fd->toObjFile(0); } #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS // A hack to get a pointer to this function put in the .dtors segment if (ident && memcmp(ident->toChars(), "_STD", 4) == 0) objmod->staticdtor(s); #endif #if DMDV2 if (irs.startaddress) { //printf("Setting start address\n"); objmod->startaddress(irs.startaddress); } #endif }
int read_member_objects_recursively(int member_index, int downlinks_from_core) { int i, j; int links = nshape[fstate.target_templ->member[member_index].shape].links; fstate.target_templ->member[member_index].downlinks_from_core = downlinks_from_core; // struct ctokenstruct ctoken; // Object looks like this: // {object_type, angle : class, class2} (plus possible comma) // link object can look like this: // {object_downlink, angle, {shape...}} //* remember to update d_code.c so it generates the process in the right format! //fpr("\n read_member_objects_recursively %i", member_index); for (i = 0; i < links; i ++) { int object_type = read_procdef(); //fpr("\n obj %i %i", i, object_type); #ifdef TEST_PROCDEF fpr("\nread object_type %i (%i)", object_type, fstate.procdef_pos); #endif if (object_type < 0 || object_type >= OBJECT_TYPES) return procdef_error("expected object type"); fstate.target_templ->member[member_index].object[i].type = object_type; int number_of_classes = read_procdef(); #ifdef TEST_PROCDEF fpr("\nread number of classes %i (%i)", number_of_classes, fstate.procdef_pos); #endif if (number_of_classes < 0 || number_of_classes >= CLASSES_PER_OBJECT) return procdef_error("wrong number of classes"); //fpr("\n number of classes %i: ", number_of_classes); j = 0; while (j < number_of_classes) { int class_index = read_procdef(); // fpr("(%i:%i), ", j, class_index); #ifdef TEST_PROCDEF fpr("\nread class_index %i (%i)", class_index, fstate.procdef_pos); #endif if (class_index < 0 || class_index >= OBJECT_CLASSES) return procdef_error("invalid class index"); fstate.target_templ->member[member_index].object[i].object_class[j] = class_index; j++; } int object_angle = read_procdef(); #ifdef TEST_PROCDEF fpr("\nread object_angle %i (%i)", object_angle, fstate.procdef_pos); #endif if (object_angle < -ANGLE_4 || object_angle > ANGLE_4) return procdef_error("invalid object angle"); if (otype[object_type].object_details.only_zero_angle_offset) { // fpr("\n Fixing angle %i to 0 (otype %i)", object_angle, object_type); object_angle = 0; // some object types can only have zero offset } fstate.target_templ->member[member_index].object[i].base_angle_offset_angle = object_angle; // fpr("\n read [%i] template %i member %i object %i angle_offset %i", fstate.procdef_pos, fstate.target_templ->template_index, member_index, i, fstate.target_templ->member[member_index].object[i].base_angle_offset_angle); fstate.target_templ->member[member_index].object[i].base_angle_offset = angle_difference_signed(0, int_angle_to_fixed(object_angle)); //fpr("\n fix oa %i base_angle %i base_angle_f %f", object_angle, fstate.target_templ->member[member_index].object[i].base_angle_offset_angle, al_fixtof(fstate.target_templ->member[member_index].object[i].base_angle_offset)); if (object_type == OBJECT_TYPE_DOWNLINK) { for (j = 1; j < GROUP_CONNECTIONS; j ++) { if (fstate.target_templ->member[member_index].connection[j].template_member_index == -1) { if (!read_member_recursively(member_index, i, j, downlinks_from_core + 1)) return 0; break; } } if (j >= GROUP_CONNECTIONS) return comp_error_text("too many connections", NULL); // not sure this is possible (there should always be enough space in the connections array) } if (cstate.error != CERR_NONE) return 0; } return 1; }
// This function can be called either from the compiler or from the template file loading functions // so don't use any compiler-related stuff. // When loading a file, compile_mode should be COMPILE_MODE_FIX or maybe BUILD static int generate_template_from_procdef(int compile_mode) { // struct ctokenstruct ctoken; //fpr("\n read A(%i,%i) ", procdef.buffer[15], procdef.buffer[16]); strcpy(fstate.target_templ->name, procdef.template_name); fstate.procdef_pos = 0; // now read in core shape: // (check for non-core shapes first because this is an obvious mistake to make) int core_shape = read_procdef(); #ifdef TEST_PROCDEF fpr("\nread core_shape %i (%i)", core_shape, fstate.procdef_pos); #endif if (core_shape < 0 || core_shape >= FIRST_NONCORE_SHAPE) return procdef_error("invalid core type."); // the error messages here are not super-helpful, but these errors shouldn't really occur fstate.target_templ->member[0].shape = core_shape; if (core_shape < FIRST_MOBILE_NSHAPE) fstate.target_templ->mobile = 0; else fstate.target_templ->mobile = 1; // Core angle offset int core_angle = read_procdef() & ANGLE_MASK; #ifdef TEST_PROCDEF fpr("\nread core_angle %i (%i)", core_angle, fstate.procdef_pos); #endif fstate.target_templ->member[0].connection_angle_offset_angle = core_angle; fstate.target_templ->member[0].group_angle_offset = int_angle_to_fixed(core_angle); fstate.target_templ->member[0].connection_angle_offset = fstate.target_templ->member[0].group_angle_offset; // fstate.target_templ->member[0].downlinks_from_core = 0; this is set by read_member_objects_recursively // read objects: if (!read_member_objects_recursively(0, 0)) return 0; if (compile_mode == COMPILE_MODE_TEST) // locked template return 1; // successful test. if (fstate.target_templ->locked) { fstate.target_templ->modified = 0; // design version of process should match source code version return 1; // if template locked, process header is parsed but ignored (except to get class name identifiers) } update_design_member_positions(fstate.target_templ); if (!finalise_template_class_lists()) return 0; calculate_template_cost_and_power(fstate.target_templ); if (!finalise_template_details(fstate.target_templ)) return 0; fstate.target_templ->modified = 0; // design version of process should match source code version return 1; }
int intercode_to_bcode(void) { int i; for (i = 0; i < BCODE_MAX; i ++) { cstate.target_bcode->op [i] = OP_nop; cstate.target_bcode->src_line [i] = 0; } // the end of the bcode is filled with stop instructions for (i = BCODE_POS_MAX; i < BCODE_MAX; i ++) { cstate.target_bcode->op [i] = OP_stop; } int intercode_length = cstate.ic_pos; cstate.bc_pos = 0; cstate.ic_pos = 0; cstate.resolve_pos = 0; // position in cstate.ic_address_resolve struct for (cstate.ic_pos = 0; cstate.ic_pos < intercode_length; cstate.ic_pos ++) { if (cstate.bc_pos >= BCODE_POS_MAX - 8) { return intercode_error_text("bcode too large"); } switch(cstate.intercode[cstate.ic_pos].type) { case IC_OP: #ifdef SANITY_CHECK if (cstate.intercode[cstate.ic_pos].value [0] < 0 || cstate.intercode[cstate.ic_pos].value [0] >= INSTRUCTIONS) { fpr("\nError: c_generate.c: intercode_to_bcode(): invalid IC_OP instruction %i at intercode %i (source line %i)", cstate.intercode[cstate.ic_pos].value [0], cstate.ic_pos, cstate.intercode[cstate.ic_pos].src_line); error_call(); } #endif write_bcode(cstate.intercode[cstate.ic_pos].value [0]); if (instruction_set[cstate.intercode[cstate.ic_pos].value [0]].operands > 0) { write_bcode(cstate.intercode[cstate.ic_pos].value [1]); } if (instruction_set[cstate.intercode[cstate.ic_pos].value [0]].operands > 1) { write_bcode(cstate.intercode[cstate.ic_pos].value [2]); } break; case IC_OP_WITH_VARIABLE_OPERAND: // This is like IC_OP but value [1] is an identifier index instead of a value #ifdef SANITY_CHECK if (cstate.intercode[cstate.ic_pos].value [0] < 0 || cstate.intercode[cstate.ic_pos].value [0] >= INSTRUCTIONS) { fpr("\nError: c_generate.c: intercode_to_bcode(): invalid IC_OP_WITH_VARIABLE_OPERAND instruction %i at intercode %i (source line %i)", cstate.intercode[cstate.ic_pos].value [0], cstate.ic_pos, cstate.intercode[cstate.ic_pos].src_line); error_call(); } if (identifier[cstate.intercode[cstate.ic_pos].value [1]].address < 0 || identifier[cstate.intercode[cstate.ic_pos].value [1]].address >= MEMORY_SIZE) { fpr("\nError: c_generate.c: intercode_to_bcode(): invalid IC_OP_WITH_VARIABLE_OPERAND operand (address %i) at intercode %i (source line %i)", identifier[cstate.intercode[cstate.ic_pos].value [1]].address, cstate.ic_pos, cstate.intercode[cstate.ic_pos].src_line); error_call(); } // unlikely to be possible as references to undeclared variables should have been caught during compilation stage. #endif write_bcode(cstate.intercode[cstate.ic_pos].value [0]); write_bcode(identifier[cstate.intercode[cstate.ic_pos].value [1]].address); break; case IC_EXIT_POINT_TRUE: cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_bcode = cstate.bc_pos; break; case IC_EXIT_POINT_FALSE: cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].false_point_bcode = cstate.bc_pos; break; case IC_LABEL_DEFINITION: identifier[cstate.intercode[cstate.ic_pos].value [0]].address = cstate.bc_pos; break; case IC_GOTO_LABEL: if (identifier[cstate.intercode[cstate.ic_pos].value [0]].type != CTOKEN_TYPE_IDENTIFIER_LABEL) return intercode_error_text("goto label not defined"); write_bcode(OP_jump_num); if (identifier[cstate.intercode[cstate.ic_pos].value [0]].address != -1) { write_bcode(identifier[cstate.intercode[cstate.ic_pos].value [0]].address); } else { if (!add_expoint_address_resolve(ADDRESS_RESOLVE_LABEL, cstate.intercode[cstate.ic_pos].value [0])) return 0; } break; case IC_IFFALSE_JUMP_TO_EXIT_POINT: write_bcode(OP_iffalse_jump); if (cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].false_point_bcode == -1) { // exit point address not yet known, so must resolve it at the end of code generation: if (!add_expoint_address_resolve(ADDRESS_RESOLVE_EX_POINT_FALSE, cstate.intercode[cstate.ic_pos].value [0])) return 0; } else write_bcode(cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].false_point_bcode); // address known cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].false_point_used = 1; break; case IC_IFTRUE_JUMP_TO_EXIT_POINT: write_bcode(OP_iftrue_jump); if (cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_bcode == -1) { // exit point address not yet known, so must resolve it at the end of code generation: if (!add_expoint_address_resolve(ADDRESS_RESOLVE_EX_POINT_TRUE, cstate.intercode[cstate.ic_pos].value [0])) return 0; } else write_bcode(cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_bcode); // address known cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_used = 1; break; case IC_JUMP_EXIT_POINT_TRUE: write_bcode(OP_jump_num); if (cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_bcode == -1) { // exit point address not yet known, so must resolve it at the end of code generation: if (!add_expoint_address_resolve(ADDRESS_RESOLVE_EX_POINT_TRUE, cstate.intercode[cstate.ic_pos].value [0])) return 0; } else write_bcode(cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_bcode); // address known cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_used = 1; break; case IC_JUMP_EXIT_POINT_FALSE: write_bcode(OP_jump_num); if (cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].false_point_bcode == -1) { // exit point address not yet known, so must resolve it at the end of code generation: if (!add_expoint_address_resolve(ADDRESS_RESOLVE_EX_POINT_FALSE, cstate.intercode[cstate.ic_pos].value [0])) return 0; } else write_bcode(cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].false_point_bcode); // address known cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].false_point_used = 1; break; case IC_NUMBER: write_bcode(cstate.intercode[cstate.ic_pos].value [0]); break; case IC_SWITCH: write_bcode(OP_switchA); if (!add_expoint_address_resolve(ADDRESS_RESOLVE_EX_POINT_TRUE, cstate.intercode[cstate.ic_pos].value [0])) return 0; write_bcode(cstate.intercode[cstate.ic_pos].value [1]); write_bcode(cstate.intercode[cstate.ic_pos].value [2]); cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_used = 1; break; case IC_JUMP_TABLE: // this just writes a number (to be used by switch code), no instruction. // cstate.target_bcode->op[cstate.bc_pos] = cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_bcode; // cstate.bc_pos ++; if (cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_bcode == -1) { // exit point address not yet known, so must resolve it at the end of code generation: if (!add_expoint_address_resolve(ADDRESS_RESOLVE_EX_POINT_TRUE, cstate.intercode[cstate.ic_pos].value [0])) return 0; } else write_bcode(cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_bcode); // address known cstate.expoint[cstate.intercode[cstate.ic_pos].value [0]].true_point_used = 1; break; default: fpr("\nError: c_generate.c: intercode_to_bcode(): invalid instruction %i at intercode %i (source line %i)", cstate.intercode[cstate.ic_pos].type, cstate.ic_pos, cstate.intercode[cstate.ic_pos].src_line); error_call(); break; // should never happen } } if (!resolve_addresses()) return 0; start_log_line(MLOG_COL_COMPILER); write_to_log("Bcode length "); write_number_to_log(cstate.bc_pos); write_to_log(" ("); write_number_to_log(BCODE_MAX); write_to_log("). Memory used "); write_number_to_log(cstate.mem_pos); write_to_log(" ("); write_number_to_log(MEMORY_SIZE); write_to_log(")."); finish_log_line(); // fpr("\n generation success! bc_pos %i ic_pos %i", cstate.bc_pos, cstate.ic_pos); return 1; // success! }
void remove_function_pointerst::remove_function_pointer( goto_programt &goto_program, goto_programt::targett target) { const code_function_callt &code= to_code_function_call(target->code); const exprt &function=code.function(); // this better have the right type code_typet call_type=to_code_type(function.type()); // refine the type in case the forward declaration was incomplete if(call_type.has_ellipsis() && call_type.parameters().empty()) { call_type.remove_ellipsis(); forall_expr(it, code.arguments()) call_type.parameters().push_back( code_typet::parametert(it->type())); } assert(function.id()==ID_dereference); assert(function.operands().size()==1); bool found_functions; const exprt &pointer=function.op0(); remove_const_function_pointerst::functionst functions; does_remove_constt const_removal_check(goto_program, ns); if(const_removal_check()) { warning() << "Cast from const to non-const pointer found, only worst case" << " function pointer removal will be done." << eom; found_functions=false; } else { remove_const_function_pointerst fpr( get_message_handler(), pointer, ns, symbol_table); found_functions=fpr(functions); // Either found_functions is true therefore the functions should not // be empty // Or found_functions is false therefore the functions should be empty assert(found_functions != functions.empty()); if(functions.size()==1) { to_code_function_call(target->code).function()=*functions.cbegin(); return; } } if(!found_functions) { if(only_resolve_const_fps) { // If this mode is enabled, we only remove function pointers // that we can resolve either to an exact funciton, or an exact subset // (e.g. a variable index in a constant array). // Since we haven't found functions, we would now resort to // replacing the function pointer with any function with a valid signature // Since we don't want to do that, we abort. return; } bool return_value_used=code.lhs().is_not_nil(); // get all type-compatible functions // whose address is ever taken for(const auto &t : type_map) { // address taken? if(address_taken.find(t.first)==address_taken.end()) continue; // type-compatible? if(!is_type_compatible(return_value_used, call_type, t.second)) continue; if(t.first=="pthread_mutex_cleanup") continue; symbol_exprt expr; expr.type()=t.second; expr.set_identifier(t.first); functions.insert(expr); } } // the final target is a skip goto_programt final_skip; goto_programt::targett t_final=final_skip.add_instruction(); t_final->make_skip(); // build the calls and gotos goto_programt new_code_calls; goto_programt new_code_gotos; for(const auto &fun : functions) { // call function goto_programt::targett t1=new_code_calls.add_instruction(); t1->make_function_call(code); to_code_function_call(t1->code).function()=fun; // the signature of the function might not match precisely fix_argument_types(to_code_function_call(t1->code)); fix_return_type(to_code_function_call(t1->code), new_code_calls); // goto final goto_programt::targett t3=new_code_calls.add_instruction(); t3->make_goto(t_final, true_exprt()); // goto to call address_of_exprt address_of; address_of.object()=fun; address_of.type()=pointer_typet(); address_of.type().subtype()=fun.type(); if(address_of.type()!=pointer.type()) address_of.make_typecast(pointer.type()); goto_programt::targett t4=new_code_gotos.add_instruction(); t4->make_goto(t1, equal_exprt(pointer, address_of)); } // fall-through if(add_safety_assertion) { goto_programt::targett t=new_code_gotos.add_instruction(); t->make_assertion(false_exprt()); t->source_location.set_property_class("pointer dereference"); t->source_location.set_comment("invalid function pointer"); } goto_programt new_code; // patch them all together new_code.destructive_append(new_code_gotos); new_code.destructive_append(new_code_calls); new_code.destructive_append(final_skip); // set locations Forall_goto_program_instructions(it, new_code) { irep_idt property_class=it->source_location.get_property_class(); irep_idt comment=it->source_location.get_comment(); it->source_location=target->source_location; it->function=target->function; if(!property_class.empty()) it->source_location.set_property_class(property_class); if(!comment.empty()) it->source_location.set_comment(comment); }
void Module::genobjfile(int multiobj) { //EEcontext *ee = env->getEEcontext(); //printf("Module::genobjfile(multiobj = %d) %s\n", multiobj, toChars()); lastmname = srcfile->toChars(); objmod->initfile(lastmname, NULL, toPrettyChars()); eictor = NULL; ictorlocalgot = NULL; sctors.setDim(0); ectorgates.setDim(0); sdtors.setDim(0); ssharedctors.setDim(0); esharedctorgates.setDim(0); sshareddtors.setDim(0); stests.setDim(0); dtorcount = 0; shareddtorcount = 0; if (doppelganger) { /* Generate a reference to the moduleinfo, so the module constructors * and destructors get linked in. */ Module *m = aimports[0]; assert(m); if (m->sictor || m->sctor || m->sdtor || m->ssharedctor || m->sshareddtor) { Symbol *s = m->toSymbol(); //objextern(s); //if (!s->Sxtrnnum) objextdef(s->Sident); if (!s->Sxtrnnum) { //printf("%s\n", s->Sident); #if 0 /* This should work, but causes optlink to fail in common/newlib.asm */ objextdef(s->Sident); #else Symbol *sref = symbol_generate(SCstatic, type_fake(TYnptr)); sref->Sfl = FLdata; dtxoff(&sref->Sdt, s, 0, TYnptr); outdata(sref); #endif } } } if (global.params.cov) { /* Create coverage identifier: * private uint[numlines] __coverage; */ cov = symbol_calloc("__coverage"); cov->Stype = type_fake(TYint); cov->Stype->Tmangle = mTYman_c; cov->Stype->Tcount++; cov->Sclass = SCstatic; cov->Sfl = FLdata; dtnzeros(&cov->Sdt, 4 * numlines); outdata(cov); slist_add(cov); covb = (unsigned *)calloc((numlines + 32) / 32, sizeof(*covb)); } for (size_t i = 0; i < members->dim; i++) { Dsymbol *member = (*members)[i]; //printf("toObjFile %s %s\n", member->kind(), member->toChars()); member->toObjFile(multiobj); } if (global.params.cov) { /* Generate * bit[numlines] __bcoverage; */ Symbol *bcov = symbol_calloc("__bcoverage"); bcov->Stype = type_fake(TYuint); bcov->Stype->Tcount++; bcov->Sclass = SCstatic; bcov->Sfl = FLdata; dtnbytes(&bcov->Sdt, (numlines + 32) / 32 * sizeof(*covb), (char *)covb); outdata(bcov); free(covb); covb = NULL; /* Generate: * _d_cover_register(uint[] __coverage, BitArray __bcoverage, string filename); * and prepend it to the static constructor. */ /* t will be the type of the functions generated: * extern (C) void func(); */ type *t = type_function(TYnfunc, NULL, 0, false, tsvoid); t->Tmangle = mTYman_c; sictor = toSymbolX("__modictor", SCglobal, t, "FZv"); cstate.CSpsymtab = &sictor->Sfunc->Flocsym; localgot = ictorlocalgot; elem *ecov = el_pair(TYdarray, el_long(TYsize_t, numlines), el_ptr(cov)); elem *ebcov = el_pair(TYdarray, el_long(TYsize_t, numlines), el_ptr(bcov)); if (config.exe == EX_WIN64) { ecov = addressElem(ecov, Type::tvoid->arrayOf(), false); ebcov = addressElem(ebcov, Type::tvoid->arrayOf(), false); } elem *e = el_params( el_long(TYuchar, global.params.covPercent), ecov, ebcov, toEfilename(), NULL); e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_DCOVER2]), e); eictor = el_combine(e, eictor); ictorlocalgot = localgot; } // If coverage / static constructor / destructor / unittest calls if (eictor || sctors.dim || ectorgates.dim || sdtors.dim || ssharedctors.dim || esharedctorgates.dim || sshareddtors.dim || stests.dim) { if (eictor) { localgot = ictorlocalgot; block *b = block_calloc(); b->BC = BCret; b->Belem = eictor; sictor->Sfunc->Fstartline.Sfilename = arg; sictor->Sfunc->Fstartblock = b; writefunc(sictor); } sctor = callFuncsAndGates(this, &sctors, &ectorgates, "__modctor"); sdtor = callFuncsAndGates(this, &sdtors, NULL, "__moddtor"); #if DMDV2 ssharedctor = callFuncsAndGates(this, &ssharedctors, (StaticDtorDeclarations *)&esharedctorgates, "__modsharedctor"); sshareddtor = callFuncsAndGates(this, &sshareddtors, NULL, "__modshareddtor"); #endif stest = callFuncsAndGates(this, &stests, NULL, "__modtest"); if (doppelganger) genmoduleinfo(); } if (doppelganger) { objmod->termfile(); return; } if (global.params.multiobj) { /* This is necessary because the main .obj for this module is written * first, but determining whether marray or massert or munittest are needed is done * possibly later in the doppelganger modules. * Another way to fix it is do the main one last. */ toModuleAssert(); toModuleUnittest(); toModuleArray(); } /* Always generate module info, because of templates and -cov. * But module info needs the runtime library, so disable it for betterC. */ if (!global.params.betterC /*|| needModuleInfo()*/) genmoduleinfo(); // If module assert for (int i = 0; i < 3; i++) { Symbol *ma; unsigned rt; unsigned bc; switch (i) { case 0: ma = marray; rt = RTLSYM_DARRAY; bc = BCexit; break; case 1: ma = massert; rt = RTLSYM_DASSERTM; bc = BCexit; break; case 2: ma = munittest; rt = RTLSYM_DUNITTESTM; bc = BCret; break; default: assert(0); } if (ma) { elem *elinnum; localgot = NULL; // Call dassert(filename, line) // Get sole parameter, linnum { Symbol *sp = symbol_calloc("linnum"); sp->Stype = type_fake(TYint); sp->Stype->Tcount++; sp->Sclass = (config.exe == EX_WIN64) ? SCshadowreg : SCfastpar; FuncParamRegs fpr(TYjfunc); fpr.alloc(sp->Stype, sp->Stype->Tty, &sp->Spreg, &sp->Spreg2); sp->Sflags &= ~SFLspill; sp->Sfl = (sp->Sclass == SCshadowreg) ? FLpara : FLfast; cstate.CSpsymtab = &ma->Sfunc->Flocsym; symbol_add(sp); elinnum = el_var(sp); } elem *efilename = el_ptr(toSymbol()); elem *e = el_var(rtlsym[rt]); e = el_bin(OPcall, TYvoid, e, el_param(elinnum, efilename)); block *b = block_calloc(); b->BC = bc; b->Belem = e; ma->Sfunc->Fstartline.Sfilename = arg; ma->Sfunc->Fstartblock = b; ma->Sclass = SCglobal; ma->Sfl = 0; ma->Sflags |= rtlsym[rt]->Sflags & SFLexit; writefunc(ma); } } objmod->termfile(); }
// call this for every member except the core int read_member_recursively(int parent_member_index, int parent_object, int parent_connection_index, int downlinks_from_core) { int child_member_index; // struct ctokenstruct ctoken; if (downlinks_from_core >= MAX_DOWNLINKS_FROM_CORE - 1) return procdef_error("component too many downlinks away from core"); for (child_member_index = parent_member_index + 1; child_member_index < GROUP_MAX_MEMBERS; child_member_index ++) { if (fstate.target_templ->member[child_member_index].exists == 0) break; } if (child_member_index >= GROUP_MAX_MEMBERS) return procdef_error("too many members"); init_templ_group_member(fstate.target_templ, child_member_index); // read member's shape: int member_nshape = read_procdef(); #ifdef TEST_PROCDEF fpr("\nread member_nshape %i (%i)", member_nshape, fstate.procdef_pos); #endif // (check for core process shapees first because this is an obvious mistake to make) if (member_nshape < FIRST_NONCORE_SHAPE) return procdef_error("only the process core can be a core shape"); if (member_nshape >= NSHAPES) return procdef_error("invalid process shape"); fstate.target_templ->member[child_member_index].shape = member_nshape; fstate.target_templ->member[child_member_index].exists = 1; // location etc can wait until later fstate.target_templ->member[child_member_index].connection[0].template_member_index = parent_member_index; fstate.target_templ->member[child_member_index].connection[0].reverse_link_index = parent_object; fstate.target_templ->member[child_member_index].connection[0].reverse_connection_index = parent_connection_index; // the final part of the connection structure, link_index, will be filled in below after the member's uplink object is found fstate.target_templ->member[parent_member_index].connection[parent_connection_index].template_member_index = child_member_index; fstate.target_templ->member[parent_member_index].connection[parent_connection_index].link_index = parent_object; fstate.target_templ->member[parent_member_index].connection[parent_connection_index].reverse_connection_index = 0; // reverse_link_index set below if (!read_member_objects_recursively(child_member_index, downlinks_from_core)) return 0; // now find the uplink: int i; int uplink_object_index = -1; for (i = 0; i < MAX_OBJECTS; i ++) { if (fstate.target_templ->member[child_member_index].object[i].type == OBJECT_TYPE_UPLINK) { if (uplink_object_index != -1) return procdef_error("member process has more than one uplink object"); uplink_object_index = i; } } fstate.target_templ->member[child_member_index].connection[0].link_index = uplink_object_index; fstate.target_templ->member[parent_member_index].connection[parent_connection_index].reverse_link_index = uplink_object_index; // The angle of the parent member's downlink object should be sufficient to work out where this member is: fstate.target_templ->member[child_member_index].connection_angle_offset_angle = fstate.target_templ->member[parent_member_index].object[parent_object].base_angle_offset_angle; fstate.target_templ->member[child_member_index].connection_angle_offset = int_angle_to_fixed(fstate.target_templ->member[child_member_index].connection_angle_offset_angle); return 1; }
void CmEvaluation::Evaluate(CStr gtW, CStr &salDir, CStr &resName, vecS &des) { int NumMethod = des.size(); // Number of different methods vector<vecD> precision(NumMethod), recall(NumMethod), tpr(NumMethod), fpr(NumMethod); static const int CN = 21; // Color Number static const char* c[CN] = {"'k'", "'b'", "'g'", "'r'", "'c'", "'m'", "'y'", "':k'", "':b'", "':g'", "':r'", "':c'", "':m'", "':y'", "'--k'", "'--b'", "'--g'", "'--r'", "'--c'", "'--m'", "'--y'" }; FILE* f = fopen(_S(resName), "w"); CV_Assert(f != NULL); fprintf(f, "clear;\nclose all;\nclc;\n\n\n%%%%\nfigure(1);\nhold on;\n"); vecD thr(NUM_THRESHOLD); for (int i = 0; i < NUM_THRESHOLD; i++) thr[i] = i * STEP; PrintVector(f, thr, "Threshold"); fprintf(f, "\n"); vecD mae(NumMethod); for (int i = 0; i < NumMethod; i++) mae[i] = Evaluate_(gtW, salDir, "_" + des[i] + ".png", precision[i], recall[i], tpr[i], fpr[i]); //Evaluate(salDir + "*" + des[i] + ".png", gtW, val[i], recall[i], t); string leglendStr("legend("); vecS strPre(NumMethod), strRecall(NumMethod), strTpr(NumMethod), strFpr(NumMethod); for (int i = 0; i < NumMethod; i++){ strPre[i] = format("Precision_%s", _S(des[i])); strRecall[i] = format("Recall_%s", _S(des[i])); strTpr[i] = format("TPR_%s", _S(des[i])); strFpr[i] = format("FPR_%s", _S(des[i])); PrintVector(f, recall[i], strRecall[i]); PrintVector(f, precision[i], strPre[i]); PrintVector(f, tpr[i], strTpr[i]); PrintVector(f, fpr[i], strFpr[i]); fprintf(f, "plot(%s, %s, %s, 'linewidth', %d);\n", _S(strRecall[i]), _S(strPre[i]), c[i % CN], i < CN ? 2 : 1); leglendStr += format("'%s', ", _S(des[i])); } leglendStr.resize(leglendStr.size() - 2); leglendStr += ");"; string xLabel = "label('Recall');\n"; string yLabel = "label('Precision')\n"; fprintf(f, "hold off;\nx%sy%s\n%s\ngrid on;\naxis([0 1 0 1]);\ntitle('Precision recall curve');\n", _S(xLabel), _S(yLabel), _S(leglendStr)); fprintf(f, "\n\n\n%%%%\nfigure(2);\nhold on;\n"); for (int i = 0; i < NumMethod; i++) fprintf(f, "plot(%s, %s, %s, 'linewidth', %d);\n", _S(strFpr[i]), _S(strTpr[i]), c[i % CN], i < CN ? 2 : 1); xLabel = "label('False positive rate');\n"; yLabel = "label('True positive rate')\n"; fprintf(f, "hold off;\nx%sy%s\n%s\ngrid on;\naxis([0 1 0 1]);\n\n\n%%%%\nfigure(3);\ntitle('ROC curve');\n", _S(xLabel), _S(yLabel), _S(leglendStr)); double betaSqr = 0.3; // As suggested by most papers for salient object detection vecD areaROC(NumMethod, 0), avgFMeasure(NumMethod, 0), maxFMeasure(NumMethod, 0); for (int i = 0; i < NumMethod; i++){ CV_Assert(fpr[i].size() == tpr[i].size() && precision[i].size() == recall[i].size() && fpr[i].size() == precision[i].size()); for (size_t t = 0; t < fpr[i].size(); t++){ double fMeasure = (1+betaSqr) * precision[i][t] * recall[i][t] / (betaSqr * precision[i][t] + recall[i][t]); avgFMeasure[i] += fMeasure/fpr[i].size(); // Doing average like this might have strange effect as in: maxFMeasure[i] = max(maxFMeasure[i], fMeasure); if (t > 0){ areaROC[i] += (tpr[i][t] + tpr[i][t - 1]) * (fpr[i][t - 1] - fpr[i][t]) / 2.0; } } fprintf(f, "%%%5s: AUC = %5.3f, MeanF = %5.3f, MaxF = %5.3f, MAE = %5.3f\n", _S(des[i]), areaROC[i], avgFMeasure[i], maxFMeasure[i], mae[i]); } PrintVector(f, areaROC, "AUC"); PrintVector(f, avgFMeasure, "MeanFMeasure"); PrintVector(f, maxFMeasure, "MaxFMeasure"); PrintVector(f, mae, "MAE"); // methodLabels = {'AC', 'SR', 'DRFI', 'GU', 'GB'}; fprintf(f, "methodLabels = {'%s'", _S(des[0])); for (int i = 1; i < NumMethod; i++) fprintf(f, ", '%s'", _S(des[i])); fprintf(f, "};\n\nbar([MeanFMeasure; MaxFMeasure; AUC]');\nlegend('Mean F_\\beta', 'Max F_\\beta', 'AUC');xlim([0 %d]);\ngrid on;\n", NumMethod+1); fprintf(f, "xticklabel_rotate([1:%d],90, methodLabels,'interpreter','none');\n", NumMethod); fprintf(f, "\n\nfigure(4);\nbar(MAE);\ntitle('MAE');\ngrid on;\nxlim([0 %d]);", NumMethod+1); fprintf(f, "xticklabel_rotate([1:%d],90, methodLabels,'interpreter','none');\n", NumMethod); fclose(f); printf("%-70s\r", ""); }
void ValueRecovery::dumpInContext(PrintStream& out, DumpContext* context) const { switch (technique()) { case InGPR: out.print(gpr()); return; case UnboxedInt32InGPR: out.print("int32(", gpr(), ")"); return; case UnboxedInt52InGPR: out.print("int52(", gpr(), ")"); return; case UnboxedStrictInt52InGPR: out.print("strictInt52(", gpr(), ")"); return; case UnboxedBooleanInGPR: out.print("bool(", gpr(), ")"); return; case UnboxedCellInGPR: out.print("cell(", gpr(), ")"); return; case UInt32InGPR: out.print("uint32(", gpr(), ")"); return; case InFPR: out.print(fpr()); return; #if USE(JSVALUE32_64) case InPair: out.print("pair(", tagGPR(), ", ", payloadGPR(), ")"); return; #endif case DisplacedInJSStack: out.printf("*%d", virtualRegister().offset()); return; case Int32DisplacedInJSStack: out.printf("*int32(%d)", virtualRegister().offset()); return; case Int52DisplacedInJSStack: out.printf("*int52(%d)", virtualRegister().offset()); return; case StrictInt52DisplacedInJSStack: out.printf("*strictInt52(%d)", virtualRegister().offset()); return; case DoubleDisplacedInJSStack: out.printf("*double(%d)", virtualRegister().offset()); return; case CellDisplacedInJSStack: out.printf("*cell(%d)", virtualRegister().offset()); return; case BooleanDisplacedInJSStack: out.printf("*bool(%d)", virtualRegister().offset()); return; case ArgumentsThatWereNotCreated: out.printf("arguments"); return; case Constant: out.print("[", inContext(constant(), context), "]"); return; case DontKnow: out.printf("!"); return; } RELEASE_ASSERT_NOT_REACHED(); }
// Call this when compiling process definition part of source code. // Reads the process structure definition from cstate.scode. // Depending on the compiler mode, may discard process structure (but always processes structure to test it and to declare classes) // Updates cstate with e.g. new scode_pos. // returns 1 on success, 0 on failure int parse_process_definition(void) { /*fpr("\n A sc_pos %i src_line %i", cstate.scode_pos, cstate.src_line); int k; for (k = 0; k < 100; k ++) { fpr("\n scode_pos %i src_line %i", k, cstate.scode.src_line [k]); } */ fstate.target_templ = cstate.templ; init_procdef(); //fpr("\n template %i A(%i,%i) ", cstate.templ->template_index, procdef.buffer [15],procdef.buffer [16]); init_template_for_design(fstate.target_templ); //fpr("B(%i,%i) ", procdef.buffer [15],procdef.buffer [16]); struct ctokenstruct ctoken; // the first thing in the scode should be #process // (deal with naming processes later) if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_HASH)) { // fpr("\n # token type %i found", ctoken.type); return comp_error(CERR_FIXER_EXPECTED_PROCESS_HEADER, &ctoken); } if (!accept_next(&ctoken, CTOKEN_TYPE_IDENTIFIER_NON_C_KEYWORD, KEYWORD_C_PROCESS)) { // fpr("\n pr token type %i found", ctoken.type); return comp_error(CERR_FIXER_EXPECTED_PROCESS_HEADER, &ctoken); } // accept template name // (this should be on the same line as #process, but technically doesn't have to be) if (accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_QUOTES)) { char template_name_string [TEMPLATE_NAME_LENGTH]; template_name_string [0] = '\0'; int read_char; int template_name_length = 0; while(TRUE) { read_char = c_get_next_char_from_scode(); if (read_char == REACHED_END_OF_SCODE) return comp_error_text("reached end of source inside string", NULL); if (read_char == 0) return comp_error_text("found null character inside string?", NULL); if (template_name_length >= TEMPLATE_NAME_LENGTH - 2) return comp_error_text("template name too long", NULL); if (read_char == '"') break; template_name_string [template_name_length] = read_char; template_name_length++; }; template_name_string [template_name_length] = '\0'; strcpy(procdef.template_name, template_name_string); } //fpr("C(%i,%i) ", procdef.buffer [15],procdef.buffer [16]); // accept classes while(accept_next(&ctoken, CTOKEN_TYPE_IDENTIFIER_NON_C_KEYWORD, KEYWORD_C_CLASS)) { if (!read_next(&ctoken)) return 0; while (TRUE) { if (ctoken.type != CTOKEN_TYPE_IDENTIFIER_NEW) return comp_error_text("expected new class name after class (word already in use?)", &ctoken); if (!procdef_declare_new_class(&ctoken)) return 0; if (accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_SEMICOLON)) break; if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_COMMA)) return comp_error_text("expected ; or , after class declaration", &ctoken); }; }; //fpr("D(%i,%i) ", procdef.buffer [15],procdef.buffer [16]); // expect open brace: // if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_BRACE_OPEN)) // return comp_error_text("expected open brace at start of process structure definition", &ctoken); // now read in core shape: // (check for non-core shapes first because this is an obvious mistake to make) if (accept_next(&ctoken, CTOKEN_TYPE_IDENTIFIER_SHAPE, -1)) return comp_error_text("the process core must be a core shape", &ctoken); if (!accept_next(&ctoken, CTOKEN_TYPE_IDENTIFIER_CORE_SHAPE, -1)) return comp_error_text("expected a core shape", &ctoken); // fstate.target_templ->member[0].shape = identifier[ctoken.identifier_index].value; int core_shape = identifier[ctoken.identifier_index].value; write_to_procdef(core_shape); #ifdef TEST_PROCDEF fpr("\nwrite core_shape %i (%i)", core_shape, procdef.buffer_length); #endif if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_COMMA)) return comp_error_text("expected comma after core shape", &ctoken); // Core angle offset if (!expect_angle(&ctoken)) return comp_error_text("core angle not a constant number?", &ctoken); write_to_procdef(ctoken.number_value); #ifdef TEST_PROCDEF fpr("\nwrite core_angle %i (%i)", ctoken.number_value, procdef.buffer_length); #endif if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_COMMA)) return comp_error_text("expected comma after core angle", &ctoken); // read objects: if (!procdef_read_member_objects_recursively(core_shape)) return 0; // expect close brace: // * actually read_member_objects_recursively should have read this. //if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_BRACE_CLOSE)) //return comp_error_text("expected open brace at start of process structure definition", &ctoken); // Finish by checking for #code directive if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_HASH)) return comp_error(CERR_FIXER_EXPECTED_CODE_HEADER, &ctoken); if (!accept_next(&ctoken, CTOKEN_TYPE_IDENTIFIER_NON_C_KEYWORD, KEYWORD_C_CODE)) return comp_error(CERR_FIXER_EXPECTED_CODE_HEADER, &ctoken); //fpr("E(%i,%i) ", procdef.buffer [15],procdef.buffer [16]); return 1; }
/* Get register by name */ Test::Register Test::getRegister(ppc::Interpreter::State &state, const std::string &name) { std::smatch smatch; /* General Purpose Register */ std::regex gpr("%r([0-9]+)"); if (std::regex_match(name, smatch, gpr) && smatch.size() == 2) { auto reg = std::stol(smatch[1].str()); if (reg >= 0 && reg <= 31) { return Register(RegisterType::Integer64, &state.reg.gpr[reg]); } } /* FPU Register */ std::regex fpr("%f([0-9]+)"); if (std::regex_match(name, smatch, fpr) && smatch.size() == 2) { auto reg = std::stol(smatch[1].str()); if (reg >= 0 && reg <= 31) { return Register(RegisterType::Double64, &state.reg.fpr[reg]); } } /* XER Link Register */ if (name.compare("%lr") == 0) { return Register(RegisterType::Integer64, &state.reg.lr); } /* XER Carry */ if (name.compare("%xer[ca]") == 0) { return Register(RegisterType::BitField64, little_endian::make_bit_field(state.reg.xer.value, 34, 35)); } /* XER Overflow */ if (name.compare("%xer[ov]") == 0) { return Register(RegisterType::BitField64, little_endian::make_bit_field(state.reg.xer.value, 33, 34)); } /* Condition Register Field */ std::regex crf("%crf([0-9]+)"); if (std::regex_match(name, smatch, crf) && smatch.size() == 2) { auto field = std::stol(smatch[1].str()); if (field >= 0 && field <= 8) { return Register(RegisterType::BitField32, state.reg.cr.crn[field]); } } /* Condition Register Bit */ std::regex crb("%crb([0-9]+)"); if (std::regex_match(name, smatch, crb) && smatch.size() == 2) { auto bit = std::stol(smatch[1].str()); if (bit >= 0 && bit <= 31) { return Register(RegisterType::BitField32, little_endian::make_bit_field(state.reg.cr.value, bit, bit)); } } return Register(); }
static int procdef_read_member_objects_recursively(int shape_index) { int i, j; // maybe verify shape_index here? int links = nshape[shape_index].links; struct ctokenstruct ctoken; // Object looks like this: // {object_type, angle : class, class2} (plus possible comma) // link object can look like this: // {object_downlink, angle, {shape...}} //* remember to update d_code.c so it generates the process in the right format! for (i = 0; i < links; i ++) { // check for end of objects list: if (accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_BRACE_CLOSE)) { while (i < links) { write_to_procdef(OBJECT_TYPE_NONE); #ifdef TEST_PROCDEF fpr("\nwrite object type %i (%i)", OBJECT_TYPE_NONE, procdef.buffer_length); #endif write_to_procdef(0); // no classes #ifdef TEST_PROCDEF fpr("\nwrite number_of_classes %i (%i)", 0, procdef.buffer_length); #endif write_to_procdef(0); // angle #ifdef TEST_PROCDEF fpr("\nwrite object_angle %i (%i)", 0, procdef.buffer_length); #endif i++; } return 1; } // expect open brace: if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_BRACE_OPEN)) return comp_error_text("expected open brace at start of object", &ctoken); // expect object type: if (!accept_next(&ctoken, CTOKEN_TYPE_IDENTIFIER_OBJECT, -1)) return comp_error_text("expected object type", &ctoken); int object_type = identifier[ctoken.identifier_index].value; write_to_procdef(object_type); #ifdef TEST_PROCDEF fpr("\nwrite object_type %i (%i)", object_type, procdef.buffer_length); #endif // fstate.target_templ->member[member_index].object[i].type = identifier[ctoken.identifier_index].value; int classes_on_object = 0; int object_class [CLASSES_PER_OBJECT]; while(accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_COLON)) { if (classes_on_object >= CLASSES_PER_OBJECT) return comp_error_text("objects can be members of maximum 4 classes", NULL); if (!read_next(&ctoken)) return 0; if (ctoken.type != CTOKEN_TYPE_IDENTIFIER_CLASS) return comp_error_text("expected class name after colon", &ctoken); object_class [classes_on_object] = identifier[ctoken.identifier_index].value; classes_on_object++; } write_to_procdef(classes_on_object); #ifdef TEST_PROCDEF fpr("\nwrite classes_on_object %i (%i)", classes_on_object, procdef.buffer_length); #endif // fpr("\nclasses on object: %i: ", classes_on_object); j = 0; while (j < classes_on_object) { write_to_procdef(object_class [j]); #ifdef TEST_PROCDEF fpr("\nwrite object_class %i (%i)", object_class [j], procdef.buffer_length); #endif j ++; } if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_COMMA)) return comp_error_text("expected , or : after object type or class", &ctoken); if (!expect_angle(&ctoken)) return comp_error_text("expected object angle", &ctoken); // should accept } here for angle 0 (or unspecified, for objects without angles) if (ctoken.number_value < -ANGLE_4) return comp_error_text("object angle offset too low (minimum is -2048)", &ctoken); if (ctoken.number_value > ANGLE_4) return comp_error_text("object angle offset too high (maximum is 2048)", &ctoken); write_to_procdef(ctoken.number_value); #ifdef TEST_PROCDEF fpr("\nwrite object_angle %i (%i)", ctoken.number_value, procdef.buffer_length); #endif // fstate.target_templ->member[member_index].object[i].base_angle_offset_angle = ctoken.number_value; // fstate.target_templ->member[member_index].object[i].base_angle_offset = angle_difference_signed(0, int_angle_to_fixed(ctoken.number_value)); if (object_type == OBJECT_TYPE_DOWNLINK) { if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_COMMA)) return comp_error_text("expected comma after downlink object angle", &ctoken); // for (j = 1; j < GROUP_CONNECTIONS; j ++) // { // if (fstate.target_templ->member[member_index].connection[j].template_member_index == -1) // { if (!procdef_read_member_recursively()) return 0; // break; // } //} // if (j >= GROUP_CONNECTIONS) // return comp_error_text("too many connections", NULL); // not sure this is possible (there should always be enough space in the connections array) } if (!accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_BRACE_CLOSE)) return comp_error_text("expected closing brace at end of object", &ctoken); // finally, accept (but don't require) a comma: accept_next(&ctoken, CTOKEN_TYPE_PUNCTUATION, CTOKEN_SUBTYPE_COMMA); // could check for error here... if (cstate.error != CERR_NONE) return 0; } return 1; // explicit object found for all links, so we've finished here }
void FuncDeclaration_toObjFile(FuncDeclaration *fd, bool multiobj) { ClassDeclaration *cd = fd->parent->isClassDeclaration(); //printf("FuncDeclaration::toObjFile(%p, %s.%s)\n", fd, fd->parent->toChars(), fd->toChars()); //if (type) printf("type = %s\n", type->toChars()); #if 0 //printf("line = %d\n", getWhere() / LINEINC); EEcontext *ee = env->getEEcontext(); if (ee->EEcompile == 2) { if (ee->EElinnum < (getWhere() / LINEINC) || ee->EElinnum > (endwhere / LINEINC) ) return; // don't compile this function ee->EEfunc = toSymbol(this); } #endif if (fd->semanticRun >= PASSobj) // if toObjFile() already run return; if (fd->type && fd->type->ty == Tfunction && ((TypeFunction *)fd->type)->next == NULL) return; // If errors occurred compiling it, such as bugzilla 6118 if (fd->type && fd->type->ty == Tfunction && ((TypeFunction *)fd->type)->next->ty == Terror) return; if (global.errors) return; if (!fd->fbody) return; UnitTestDeclaration *ud = fd->isUnitTestDeclaration(); if (ud && !global.params.useUnitTests) return; if (multiobj && !fd->isStaticDtorDeclaration() && !fd->isStaticCtorDeclaration()) { obj_append(fd); return; } if (fd->semanticRun == PASSsemanticdone) { /* What happened is this function failed semantic3() with errors, * but the errors were gagged. * Try to reproduce those errors, and then fail. */ fd->error("errors compiling the function"); return; } assert(fd->semanticRun == PASSsemantic3done); assert(fd->ident != Id::empty); for (FuncDeclaration *fd2 = fd; fd2; ) { if (fd2->inNonRoot()) return; if (fd2->isNested()) fd2 = fd2->toParent2()->isFuncDeclaration(); else break; } FuncDeclaration *fdp = fd->toParent2()->isFuncDeclaration(); if (fd->isNested()) { if (fdp && fdp->semanticRun < PASSobj) { if (fdp->semantic3Errors) return; /* Can't do unittest's out of order, they are order dependent in that their * execution is done in lexical order. */ if (UnitTestDeclaration *udp = fdp->isUnitTestDeclaration()) { udp->deferredNested.push(fd); return; } } } if (fd->isArrayOp && isDruntimeArrayOp(fd->ident)) { // Implementation is in druntime return; } // start code generation fd->semanticRun = PASSobj; if (global.params.verbose) fprintf(global.stdmsg, "function %s\n", fd->toPrettyChars()); Symbol *s = toSymbol(fd); func_t *f = s->Sfunc; // tunnel type of "this" to debug info generation if (AggregateDeclaration* ad = fd->parent->isAggregateDeclaration()) { ::type* t = Type_toCtype(ad->getType()); if (cd) t = t->Tnext; // skip reference f->Fclass = (Classsym *)t; } #if TARGET_WINDOS /* This is done so that the 'this' pointer on the stack is the same * distance away from the function parameters, so that an overriding * function can call the nested fdensure or fdrequire of its overridden function * and the stack offsets are the same. */ if (fd->isVirtual() && (fd->fensure || fd->frequire)) f->Fflags3 |= Ffakeeh; #endif #if TARGET_OSX s->Sclass = SCcomdat; #else s->Sclass = SCglobal; #endif for (Dsymbol *p = fd->parent; p; p = p->parent) { if (p->isTemplateInstance()) { s->Sclass = SCcomdat; break; } } /* Vector operations should be comdat's */ if (fd->isArrayOp) s->Sclass = SCcomdat; if (fd->isNested()) { //if (!(config.flags3 & CFG3pic)) // s->Sclass = SCstatic; f->Fflags3 |= Fnested; /* The enclosing function must have its code generated first, * in order to calculate correct frame pointer offset. */ if (fdp && fdp->semanticRun < PASSobj) { toObjFile(fdp, multiobj); } } else { const char *libname = (global.params.symdebug) ? global.params.debuglibname : global.params.defaultlibname; // Pull in RTL startup code (but only once) if (fd->isMain() && onlyOneMain(fd->loc)) { #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS objmod->external_def("_main"); objmod->ehsections(); // initialize exception handling sections #endif #if TARGET_WINDOS if (global.params.mscoff) { objmod->external_def("main"); objmod->ehsections(); // initialize exception handling sections } else { objmod->external_def("_main"); objmod->external_def("__acrtused_con"); } #endif objmod->includelib(libname); s->Sclass = SCglobal; } else if (strcmp(s->Sident, "main") == 0 && fd->linkage == LINKc) { #if TARGET_WINDOS if (global.params.mscoff) { objmod->includelib("LIBCMT"); objmod->includelib("OLDNAMES"); } else { objmod->external_def("__acrtused_con"); // bring in C startup code objmod->includelib("snn.lib"); // bring in C runtime library } #endif s->Sclass = SCglobal; } #if TARGET_WINDOS else if (fd->isWinMain() && onlyOneMain(fd->loc)) { if (global.params.mscoff) { objmod->includelib("uuid"); objmod->includelib("LIBCMT"); objmod->includelib("OLDNAMES"); objmod->ehsections(); // initialize exception handling sections } else { objmod->external_def("__acrtused"); } objmod->includelib(libname); s->Sclass = SCglobal; } // Pull in RTL startup code else if (fd->isDllMain() && onlyOneMain(fd->loc)) { if (global.params.mscoff) { objmod->includelib("uuid"); objmod->includelib("LIBCMT"); objmod->includelib("OLDNAMES"); objmod->ehsections(); // initialize exception handling sections } else { objmod->external_def("__acrtused_dll"); } objmod->includelib(libname); s->Sclass = SCglobal; } #endif } symtab_t *symtabsave = cstate.CSpsymtab; cstate.CSpsymtab = &f->Flocsym; // Find module m for this function Module *m = NULL; for (Dsymbol *p = fd->parent; p; p = p->parent) { m = p->isModule(); if (m) break; } IRState irs(m, fd); Dsymbols deferToObj; // write these to OBJ file later irs.deferToObj = &deferToObj; symbol *shidden = NULL; Symbol *sthis = NULL; tym_t tyf = tybasic(s->Stype->Tty); //printf("linkage = %d, tyf = x%x\n", linkage, tyf); int reverse = tyrevfunc(s->Stype->Tty); assert(fd->type->ty == Tfunction); TypeFunction *tf = (TypeFunction *)fd->type; RET retmethod = retStyle(tf); if (retmethod == RETstack) { // If function returns a struct, put a pointer to that // as the first argument ::type *thidden = Type_toCtype(tf->next->pointerTo()); char hiddenparam[5+4+1]; static int hiddenparami; // how many we've generated so far sprintf(hiddenparam,"__HID%d",++hiddenparami); shidden = symbol_name(hiddenparam,SCparameter,thidden); shidden->Sflags |= SFLtrue | SFLfree; if (fd->nrvo_can && fd->nrvo_var && fd->nrvo_var->nestedrefs.dim) type_setcv(&shidden->Stype, shidden->Stype->Tty | mTYvolatile); irs.shidden = shidden; fd->shidden = shidden; } else { // Register return style cannot make nrvo. // Auto functions keep the nrvo_can flag up to here, // so we should eliminate it before entering backend. fd->nrvo_can = 0; } if (fd->vthis) { assert(!fd->vthis->csym); sthis = toSymbol(fd->vthis); irs.sthis = sthis; if (!(f->Fflags3 & Fnested)) f->Fflags3 |= Fmember; } // Estimate number of parameters, pi size_t pi = (fd->v_arguments != NULL); if (fd->parameters) pi += fd->parameters->dim; // Create a temporary buffer, params[], to hold function parameters Symbol *paramsbuf[10]; Symbol **params = paramsbuf; // allocate on stack if possible if (pi + 2 > 10) // allow extra 2 for sthis and shidden { params = (Symbol **)malloc((pi + 2) * sizeof(Symbol *)); assert(params); } // Get the actual number of parameters, pi, and fill in the params[] pi = 0; if (fd->v_arguments) { params[pi] = toSymbol(fd->v_arguments); pi += 1; } if (fd->parameters) { for (size_t i = 0; i < fd->parameters->dim; i++) { VarDeclaration *v = (*fd->parameters)[i]; //printf("param[%d] = %p, %s\n", i, v, v->toChars()); assert(!v->csym); params[pi + i] = toSymbol(v); } pi += fd->parameters->dim; } if (reverse) { // Reverse params[] entries for (size_t i = 0; i < pi/2; i++) { Symbol *sptmp = params[i]; params[i] = params[pi - 1 - i]; params[pi - 1 - i] = sptmp; } } if (shidden) { #if 0 // shidden becomes last parameter params[pi] = shidden; #else // shidden becomes first parameter memmove(params + 1, params, pi * sizeof(params[0])); params[0] = shidden; #endif pi++; } if (sthis) { #if 0 // sthis becomes last parameter params[pi] = sthis; #else // sthis becomes first parameter memmove(params + 1, params, pi * sizeof(params[0])); params[0] = sthis; #endif pi++; } if ((global.params.isLinux || global.params.isOSX || global.params.isFreeBSD || global.params.isSolaris) && fd->linkage != LINKd && shidden && sthis) { /* swap shidden and sthis */ Symbol *sp = params[0]; params[0] = params[1]; params[1] = sp; } for (size_t i = 0; i < pi; i++) { Symbol *sp = params[i]; sp->Sclass = SCparameter; sp->Sflags &= ~SFLspill; sp->Sfl = FLpara; symbol_add(sp); } // Determine register assignments if (pi) { FuncParamRegs fpr(tyf); for (size_t i = 0; i < pi; i++) { Symbol *sp = params[i]; if (fpr.alloc(sp->Stype, sp->Stype->Tty, &sp->Spreg, &sp->Spreg2)) { sp->Sclass = (config.exe == EX_WIN64) ? SCshadowreg : SCfastpar; sp->Sfl = (sp->Sclass == SCshadowreg) ? FLpara : FLfast; } } } // Done with params if (params != paramsbuf) free(params); params = NULL; if (fd->fbody) { localgot = NULL; Statement *sbody = fd->fbody; Blockx bx; memset(&bx,0,sizeof(bx)); bx.startblock = block_calloc(); bx.curblock = bx.startblock; bx.funcsym = s; bx.scope_index = -1; bx.classdec = cd; bx.member = fd; bx.module = fd->getModule(); irs.blx = &bx; /* Doing this in semantic3() caused all kinds of problems: * 1. couldn't reliably get the final mangling of the function name due to fwd refs * 2. impact on function inlining * 3. what to do when writing out .di files, or other pretty printing */ if (global.params.trace && !fd->isCMain()) { /* The profiler requires TLS, and TLS may not be set up yet when C main() * gets control (i.e. OSX), leading to a crash. */ /* Wrap the entire function body in: * trace_pro("funcname"); * try * body; * finally * _c_trace_epi(); */ StringExp *se = StringExp::create(Loc(), s->Sident); se->type = Type::tstring; se->type = se->type->semantic(Loc(), NULL); Expressions *exps = Expressions_create(); exps->push(se); FuncDeclaration *fdpro = FuncDeclaration::genCfunc(NULL, Type::tvoid, "trace_pro"); Expression *ec = VarExp::create(Loc(), fdpro); Expression *e = CallExp::create(Loc(), ec, exps); e->type = Type::tvoid; Statement *sp = ExpStatement::create(fd->loc, e); FuncDeclaration *fdepi = FuncDeclaration::genCfunc(NULL, Type::tvoid, "_c_trace_epi"); ec = VarExp::create(Loc(), fdepi); e = CallExp::create(Loc(), ec); e->type = Type::tvoid; Statement *sf = ExpStatement::create(fd->loc, e); Statement *stf; if (sbody->blockExit(fd, false) == BEfallthru) stf = CompoundStatement::create(Loc(), sbody, sf); else stf = TryFinallyStatement::create(Loc(), sbody, sf); sbody = CompoundStatement::create(Loc(), sp, stf); } buildClosure(fd, &irs); #if TARGET_WINDOS if (fd->isSynchronized() && cd && config.flags2 & CFG2seh && !fd->isStatic() && !sbody->usesEH() && !global.params.trace) { /* The "jmonitor" hack uses an optimized exception handling frame * which is a little shorter than the more general EH frame. */ s->Sfunc->Fflags3 |= Fjmonitor; } #endif Statement_toIR(sbody, &irs); bx.curblock->BC = BCret; f->Fstartblock = bx.startblock; // einit = el_combine(einit,bx.init); if (fd->isCtorDeclaration()) { assert(sthis); for (block *b = f->Fstartblock; b; b = b->Bnext) { if (b->BC == BCret) { b->BC = BCretexp; b->Belem = el_combine(b->Belem, el_var(sthis)); } } } } // If static constructor if (fd->isSharedStaticCtorDeclaration()) // must come first because it derives from StaticCtorDeclaration { ssharedctors.push(s); } else if (fd->isStaticCtorDeclaration()) { sctors.push(s); } // If static destructor if (fd->isSharedStaticDtorDeclaration()) // must come first because it derives from StaticDtorDeclaration { SharedStaticDtorDeclaration *f = fd->isSharedStaticDtorDeclaration(); assert(f); if (f->vgate) { /* Increment destructor's vgate at construction time */ esharedctorgates.push(f); } sshareddtors.shift(s); } else if (fd->isStaticDtorDeclaration()) { StaticDtorDeclaration *f = fd->isStaticDtorDeclaration(); assert(f); if (f->vgate) { /* Increment destructor's vgate at construction time */ ectorgates.push(f); } sdtors.shift(s); } // If unit test if (ud) { stests.push(s); } if (global.errors) { // Restore symbol table cstate.CSpsymtab = symtabsave; return; } writefunc(s); // Restore symbol table cstate.CSpsymtab = symtabsave; if (fd->isExport()) objmod->export_symbol(s, Para.offset); for (size_t i = 0; i < irs.deferToObj->dim; i++) { Dsymbol *s = (*irs.deferToObj)[i]; toObjFile(s, false); } if (ud) { for (size_t i = 0; i < ud->deferredNested.dim; i++) { FuncDeclaration *fd = ud->deferredNested[i]; toObjFile(fd, false); } } #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS // A hack to get a pointer to this function put in the .dtors segment if (fd->ident && memcmp(fd->ident->toChars(), "_STD", 4) == 0) objmod->staticdtor(s); #endif if (irs.startaddress) { //printf("Setting start address\n"); objmod->startaddress(irs.startaddress); } }
StrongClassifier* adaboost_learning(CascadeClassifier *cc, std::list<float *> &positiveSet, int numPos, std::list<float *> &negativeSet, int numNeg, std::list<float *> &validateSet, std::vector<Feature *> &featureSet, float maxfpr, float maxfnr) { StrongClassifier *sc = new StrongClassifier; int width = cc->WIDTH; int height = cc->HEIGHT; float *weights = NULL, *values = NULL; int sampleSize = numPos + numNeg; int fsize = featureSet.size(); float cfpr = 1.0; init_weights(&weights, numPos, numNeg); values = new float[sampleSize]; memset(values, 0, sizeof(float) * sampleSize); while(cfpr > maxfpr) { std::list<float *>::iterator iter; float minError = 1, error, beta; WeakClassifier *bestWC = NULL; for(int i = 0; i < fsize; i++) { Feature *feat = new Feature; WeakClassifier *wc = new WeakClassifier; init_feature(feat, featureSet[i]); init_weak_classifier(wc, 0, 0, feat); iter = positiveSet.begin(); for(int j = 0; j < numPos; j++, iter++) values[j] = get_value(feat, *iter, width, 0, 0); iter = negativeSet.begin(); for(int j = 0; j < numNeg; j++, iter++) values[j + numPos] = get_value(feat, *iter, width, 0, 0); error = train(wc, values, numPos, numNeg, weights); if(error < minError) { if(bestWC != NULL){ clear(bestWC); bestWC = NULL; } bestWC = wc; minError = error; printf("Select best weak classifier, min error: %f\r", minError); fflush(stdout); } else delete wc; } assert(minError > 0); printf("best weak classifier error = %f \n", minError); beta = minError / (1 - minError); int tp = 0; iter = positiveSet.begin(); for(int i = 0; i < numPos; i++, iter++){ if(classify(bestWC, *iter, width, 0, 0) == 1){ weights[i] *= beta; tp ++; } } int tn = 0; iter = negativeSet.begin(); for(int i = numPos; i < sampleSize; i++, iter++){ if(classify(bestWC, *iter, width, 0, 0) != 1){ weights[i] *= beta; tn++; } } update_weights(weights, numPos, numNeg); printf("TP = %d, TN = %d, beta = %f, log(1/beta) = %f\n", tp, tn, beta, log(1/beta)); add(sc, bestWC, log(1/beta)); train(sc, positiveSet, width, maxfnr); cfpr = fpr(sc, validateSet, width); printf("fpr validate: %f\n", fpr(sc, validateSet, width)); printf("fpr negative: %f\n", fpr(sc, negativeSet, width)); printf("\n"); } printf("\nWeak classifier size %ld\n", sc->wcs.size()); delete [] values; delete [] weights; return sc; }