[m-dev.] Re: pragma fact_table

Fergus Henderson fjh at cs.mu.oz.au
Wed Feb 26 18:16:08 AEDT 1997


David Matthew OVERTON, you wrote:
> 
> compiler/inlining.m:
> 	Stop `model_non' `pragma c_code' being inlined unless it hash

s/hash/has/

> -		{
> -			Float f = %s, g, h;
> -			if (f <= 0.0) f = -f;
> -			if (f == 0.0) f = 1e-15;
> -			h = log(f);
> -			h = ceil(h);
> -			g = exp(h);
> -			g = f / g * 2147483647.0;
> -			if (h <= 0.0) h = -h;
> -			hashval = (Integer)g %% hashsize;
> -			hashval = ((Integer)h + 31*hashval) %% hashsize;
> -		}
> +		hashval = hash_float(%s) %% hashsize;

You should not assume that the result of hash_float is non-negative.

> -				ind = %s.index;
> +				ind = (Word)%s.index;

Put a space after the ')'.

>  generate_fact_lookup_code(PredName, [pragma_var(_, VarName, Mode)|PragmaVars],
> +		[Type | Types], ModuleInfo, ArgNum, FactTableSize, C_Code) :-
>  	NextArgNum is ArgNum + 1,
> +	( mode_is_fully_output(ModuleInfo, Mode) ->
>  		C_Code_Template = 
> +		"\t\t%s = %smercury__%s_fact_table[ind/%d][ind%%%d].V_%d;\n",
> +		( Type = term__functor(term__atom("string"), [], _) ->
> +			% Cast ConstString -> Word -> String to avoid 
> +			% gcc warning "assignment discards `const'".
> +			% XXX Is this safe or should I be copying the string
> +			% onto the heap?
> +			Cast = "(String)(Word)"

Put a space after each ')'.

The code is potentially unsafe if the user used a `uo' mode.
Since mode_is_fully_output allows `uo' modes, yes, it is unsafe.
Someone might want to write code which destructively updates strings, e.g.

	:- func to_upper(string::di) = (string::uo) is det.
	:- pragma c_code(to_upper(S0) = S), will_not_call_mercury, "{
		int i;
		for (i = 0; i < strlen(S0); i++) {
			S0[i] = toupper(S0);
		}
		S = S0;
	}").
		
On the other hand you don't want to copy to the heap in the normal `out'
mode case.  So you should use inst_is_not_partly_unique to check.

But even in the non-unique case, there is still a possible problem --
you should use make_aligned_string() from runtime/mercury_string.h to
ensure that strings are properly aligned.

By the way, the code we currently generate for

	:- pred p(string::uo).
	p("blah").

is also unsafe in the same sense -- we need to fix that before
we claim to support unique modes.

> +	% Convert an rval (represented as a string), from a C type to
> +	% a mercury C type. (ie. convert strings and floats to words).
> +:- pred convert_type_to_mercury(string, type, string).
> +:- mode convert_type_to_mercury(in, in, out) is det.
> +
> +	% Convert an rval (represented as a string), from a mercury C type to
> +	% a C type. (ie. convert words to strings and floats if required).
> +:- pred convert_type_from_mercury(string, type, string).
> +:- mode convert_type_from_mercury(in, in, out) is det.

Insert "Generate C code to ..." at the start of and append "and return
the resulting C code as a string" at the end of both of those comments.

> +			( { AssumeGmake = no} ->
> +				io__write_strings(DepStream,
> +					[ModuleName, ".fact_tables.os = "]),
> +				write_dependencies_list(FactDeps, ".o",
> +					DepStream),
> +				io__write_strings(DepStream, [
> +					"\n\n", ModuleName, 
> +					".fact_tables.cs = $(", ModuleName,
> +					".fact_tables.os:.o=.c)\n\n"
> +				])

That code assumes GNU make.  The `$(blah:.o=.c)' syntax is not portable
to other version of make.

Can I please see another diff for fact_table.m relative to the version
as at this diff, and another diff for modules.m?

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list