[Aldor-l] Dangerous use of GMP

Ralf Hemmecke ralf at hemmecke.de
Wed Jul 2 09:09:13 EDT 2008


Hi Pippijn, hello Peter,

When I say

aldor -fc -q5 salfltgmp.as

I get

static FiWord
CF26_coerce(FiEnv e1, FiWord P0_a)
{
         PFmt14 T2;
         PFmt13 T0, T1;
         PFmt21 l1;
         l1 = (PFmt21) fiEnvLevel(e1);
         if ((FiBool) l1->X57_b64_QMARK_) goto L0;
         T1 = fi0RecNew(struct Fmt13 , CENSUS_Rec);
         T1->X0_pr = (FiWord) 0L;
         T1->X1_sz = (FiWord) 0L;
         T1->X2_expo = (FiWord) 0L;
         T1->X3_lmbs = (FiWord) fiNil;
         T0 = T1;
L1:	__gmpf_init((FiWord) T0);
         __gmpf_set_d((FiWord) T0, P0_a);
         return (FiWord) T0;
L0:	T2 = fi0RecNew(struct Fmt14 , CENSUS_Rec);
         T2->X0_szpr = (FiWord) 0L;
         T2->X1_expo = (FiWord) 0L;
         T2->X2_lmbs = (FiWord) fiNil;
         T0 = (PFmt13) T2;
         goto L1;
}

with

struct Fmt13 {
         FiWord X0_pr;
         FiWord X1_sz;
         FiWord X2_expo;
         FiWord X3_lmbs;
};
struct Fmt14 {
         FiWord X0_szpr;
         FiWord X1_expo;
         FiWord X2_lmbs;
};

being the equivalent of

	coerce(a:DoubleFloat):%		== {
		e:% := new();
		____gmpf__set__d(rep e, a);
		e;
	}

         new():%                         == {
		n: Pointer := {
			b64? => [0,0,nil]$Rec64 pretend Pointer;
			[0,0,0,nil]$Rec32 pretend Pointer;
		}
                 ____gmpf__init(n);
		per n;
	}

So the structures given to __gmpf_init() differ according to whether the 
program runs on 32 or 64 bits. Seems that I didn't understand your 
problem. Could you make that issue a bit more precise?

Now if gmp on a 64 bit machine requires the second argument of 
__gmpf_set_d() to be a float instead of a pointer to it, then there must 
be made some change to the .as sources. Actually, it would be 
interesting to know whether Aldor deals with single and double floats 
*always* in a boxed form.

Peter, do you happen to know?

In that case maybe something like

   coerce(a:DoubleFloat):%		== {
	e:% := new();
	if b64? then {
		Box ==> Record(myfloatdata: Pointer);
		import from Box;
		f: Pointer := (a pretend Box).myfloatdata;
		____gmpf__set__d(rep e, (f pretend DoubleFloat));
	} else {
		____gmpf__set__d(rep e, a);
	}
	e;
   }

might help. It leads to

static FiWord
CF26_coerce(FiEnv e1, FiWord P0_a)
{
         PFmt14 T3;
         PFmt13 T1, T2;
         FiWord T0_f;
         PFmt22 l1;
         l1 = (PFmt22) fiEnvLevel(e1);
         if ((FiBool) l1->X57_b64_QMARK_) goto L2;
         T2 = fi0RecNew(struct Fmt13 , CENSUS_Rec);
         T2->X0_pr = (FiWord) 0L;
         T2->X1_sz = (FiWord) 0L;
         T2->X2_expo = (FiWord) 0L;
         T2->X3_lmbs = (FiWord) fiNil;
         T1 = T2;
L3:	__gmpf_init((FiWord) T1);
         if ((FiBool) l1->X57_b64_QMARK_) goto L0;
         __gmpf_set_d((FiWord) T1, P0_a);
L1:	return (FiWord) T1;
L0:	T0_f = ((PFmt19) P0_a)->X0_myfloatdata;
         __gmpf_set_d((FiWord) T1, T0_f);
         goto L1;
L2:	T3 = fi0RecNew(struct Fmt14 , CENSUS_Rec);
         T3->X0_szpr = (FiWord) 0L;
         T3->X1_expo = (FiWord) 0L;
         T3->X2_lmbs = (FiWord) fiNil;
         T1 = (PFmt13) T3;
         goto L3;
}

Does that you more right to you, Pippijn?

In any case, my change of the .as stuff looks very ugly and dangerous.

Ralf

PS: Unfortunately, I could not find any contact data of Helene Prieto 
(the author of sal_fltgmp.as).



On 06/26/2008 10:33 PM, Pippijn van Steenhoven wrote:
> Hi List,
> 
> in libaldor, the file sal_fltgmp.as uses GMP functions in 'coerce' as
> follows:
> 
> struct Fmt13 {
>         FiWord X0_pr;
>         FiWord X1_sz;
>         FiWord X2_expo;
>         FiWord X3_lmbs;
> };
> [...]
> struct Fmt32 {
>         FiDFlo X0_float;
> };
> [...]
> static FiWord
> CF24_coerce(FiEnv e1, FiWord P0_a)
> {
>         [...]
>         PFmt13 T2, T3;
>         PFmt32 T1;
>         [...]
>         T1 = fi0RecNew(struct Fmt32 , CENSUS_Rec);
>         [...]
>         T3 = fi0RecNew(struct Fmt13 , CENSUS_Rec);
>         [...]
>         T2 = T3;
> L1:     __gmpf_init((FiWord) T2);
>         __gmpf_set_d((FiWord) T2, T1);
>         [...]
> }
> 
> 1) Fmt13 is not what __gmpf_init expects. What the function expects is
>    more like
>    struct mpf_struct {
>         int X0_pr;
>         int X1_sz;
>         int X2_expo;
>         Pointer X3_lmbs;
>    };
>    This is fine on 32 bit platforms, but on 64 bit platforms with the
>    LP64 data model, this breaks horribly.
> 2) __gmpf_set_d expects the same struct as above as first argument and a
>    plain double as second argument. T1, however, is a pointer to a struct
>    containing a plain double. It will *always* receive garbage. Passing
>    T1->X0_float would work, but currently, there is no support for
>    something like that.
> 
> This seems to be an inherent problem with the way Aldor generates C code.
> How should this be solved? I really don't have many ideas on this one.
> The compiler expects the functions to nicely work with those arguments,
> but they don't. The only solution I can think of is wrapping all foreign
> functions.



More information about the Aldor-l mailing list