Esempio n. 1
0
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;

}
Esempio n. 2
0
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);
        }
    }
}
Esempio n. 3
0
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);
    }
}
Esempio n. 4
0
// 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;

}
Esempio n. 5
0
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;
    }
}
Esempio n. 6
0
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()));
}
Esempio n. 7
0
// 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);

}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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;
	}

}
Esempio n. 10
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);

}
Esempio n. 11
0
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);

}
Esempio n. 12
0
// 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;

}
Esempio n. 13
0
// 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);

}
Esempio n. 14
0
// 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;

}
Esempio n. 15
0
// 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;

}
Esempio n. 16
0
// 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;

}
Esempio n. 17
0
File: glue.c Progetto: sgraf812/dmd
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
}
Esempio n. 18
0
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;

}
Esempio n. 19
0
// 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;

}
Esempio n. 20
0
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);
  }
Esempio n. 22
0
File: glue.c Progetto: alexrp/dmd
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();
}
Esempio n. 23
0
// 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;

}
Esempio n. 24
0
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();
}
Esempio n. 26
0
// 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;

}
Esempio n. 27
0
/* 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();
}
Esempio n. 28
0
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

}
Esempio n. 29
0
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);
    }
}
Esempio n. 30
0
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;
}