[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