Dangerous use of GMP

View: New views
3 Messages — Rating Filter:   Alert me  

Dangerous use of GMP

by pip88nl :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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.

--
Pippijn van Steenhoven


_______________________________________________
Aldor-l mailing list
Aldor-l@...
http://aldor.org/mailman/listinfo/aldor-l_aldor.org

signature.asc (196 bytes) Download Attachment

Re: Dangerous use of GMP

by pip88nl :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jun 26, 2008 at 10:33:21PM +0200, Pippijn van Steenhoven wrote:
> struct Fmt32 {
>         FiDFlo X0_float;
> };
>    T1, however, is a pointer to a struct
>    containing a plain double.

This is intended behaviour, by the way. SingleFloat is passed as float,
DoubleFloat is passed as double* which would be equal to that struct. How
do we solve this? Can aldor dereference DoubleFloats?

Regards,

--
Pippijn van Steenhoven


_______________________________________________
Aldor-l mailing list
Aldor-l@...
http://aldor.org/mailman/listinfo/aldor-l_aldor.org

signature.asc (196 bytes) Download Attachment

Re: Dangerous use of GMP

by Ralf Hemmecke :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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.

_______________________________________________
Aldor-l mailing list
Aldor-l@...
http://aldor.org/mailman/listinfo/aldor-l_aldor.org