[M3devel] [M3commit] CVS Update: cm3

Jay K jay.krell at cornell.edu
Sun May 9 01:49:13 CEST 2010


It's not a closed system. Modula-3 can call C can call C++ can call Modula-3, etc., and they can call raise exceptions.
I'm not sure what the C exception story is on all platforms, but at least on Windows there is RaiseException.

Green book doesn't mention m3-libs/m3core/src/Unix, but it exists anyway.

 - Jay

----------------------------------------
> To: hosking at cs.purdue.edu
> Date: Sat, 8 May 2010 16:43:09 -0700
> From: mika at async.async.caltech.edu
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] [M3commit] CVS Update: cm3
>
> I've been following the discussion at a distance and am trying to understand
> what problem is being guarded against?
>
> The possibility that users change the signal mask? Signal mask is not
> part of Modula-3. I think a programmer who messes with the signal mask
> shouldn't expect Modula-3 to restore it for him when it switches threads,
> processes exceptions, etc.
>
> If you want to provide hooks for it that would be nice but I think it's
> strictly optional.
>
> "Correctness" should (as always) mean correctness w.r.t. the Green Book,
> which makes no mention at all of signals... It does mention FloatMode
> however (page 75).
>
> Mika
>
> Tony Hosking writes:
>>
>>--Apple-Mail-78-848772270
>>Content-Transfer-Encoding: quoted-printable
>>Content-Type: text/plain;
>> charset=us-ascii
>>
>>I think we can argue that a programmer should program around this using =
>>TRY...FINALLY (i.e., even if they used FloatMode).
>>
>>So, I think we are safe with jmpbuf instead of sigjmpbuf.
>>
>>Antony Hosking | Associate Professor | Computer Science | Purdue =
>>University
>>305 N. University Street | West Lafayette | IN 47907 | USA
>>Office +1 765 494 6001 | Mobile +1 765 427 5484
>>
>>
>>
>>
>>On 8 May 2010, at 18:56, Jay K wrote:
>>
>>>=20
>>> Is "proper" saving/restoring as much as we can think of, or is it =
>>fast, or is it matching Ada and C++, or .. ?
>>> Ada and C++ (gnat and g++) have often/historically used =
>>setjmp/longjmp.
>>> configure -enable-sjlj-exceptions
>>> It might be interesting to see if they try to avoid the signal mask =
>>versions when they use setjmp/longjmp.
>>> Lately they use table-based unwinding on platforms that they can -- =
>>which is to say, I *really* doubt
>>> they save/restore the signal mask, but they might.
>>>=20
>>>=20
>>> - Jay
>>>=20
>>> ----------------------------------------
>>>> Subject: Re: [M3commit] CVS Update: cm3
>>>> From: hosking at cs.purdue.edu
>>>> Date: Sat, 8 May 2010 18:51:18 -0400
>>>> CC: jkrell at elego.de; m3commit at elegosoft.com
>>>> To: jay.krell at cornell.edu
>>>>=20
>>>>=20
>>>>=20
>>>> On 8 May 2010, at 18:38, Jay K wrote:
>>>>=20
>>>>> Or, understood, you really think we might throw around a signal mask =
>>change?
>>>>=20
>>>> It's possible.
>>>>=20
>>>>> Realize also that sigsetjmp or setjmp, whichever we use, is called =
>>incredibly often, and sigsetjmp is likely
>>>>> much much slower. Also notice..this I'll have to check...have we =
>>ever called sigsetjmp?
>>>>> Well, no, I doubt it. But maybe setjmp vs. _setjmp.
>>>>> Again though, this can be significantly slow.
>>>>>=20
>>>>>=20
>>>>> Ultimately as well...see..I started this email without a firm =
>>opinion, but now I'm "firming" toward the change I made.
>>>>> Consider C++ exceptions. Consider libunwind. Consider the SPARC =
>>stack walker (which I have to look at).
>>>>> Do they save/restore signal masks? I doubt it. Maybe. We can look =
>>into it. But I doubt it.
>>>>=20
>>>> We should confirm.
>>>>=20
>>>>> Raising an exception can indeed by slow. But entering a function =
>>with finally (or destructors) should not be overly so.
>>>>=20
>>>> Ultimately, we should use proper stack unwinding wherever possible.
>>>>=20
>>>>>=20
>>>>>=20
>>>>> - Jay
>>>>>=20
>>>>> ----------------------------------------
>>>>>> From: hosking at cs.purdue.edu
>>>>>> Date: Sat, 8 May 2010 18:28:36 -0400
>>>>>> To: jkrell at elego.de
>>>>>> CC: m3commit at elegosoft.com
>>>>>> Subject: Re: [M3commit] CVS Update: cm3
>>>>>>=20
>>>>>> Ah, now I remember. sigjmpbuf is important for unwinding on =
>>exception to make sure that if we unwind through a frame where the =
>>programmer changed the signal mask that we also restore the signal mask =
>>of the caller. I think you also probably break things like FloatMode by =
>>not restoring the signal mask properly.
>>>>>>=20
>>>>>> On 9 May 2010, at 00:09, Jay Krell wrote:
>>>>>>=20
>>>>>>> CVSROOT: /usr/cvs
>>>>>>> Changes by: jkrell at birch. 10/05/09 00:09:58
>>>>>>>=20
>>>>>>> Modified files:
>>>>>>> cm3/m3-sys/m3middle/src/: Target.i3 Target.m3
>>>>>>>=20
>>>>>>> Log message:
>>>>>>> add SPARC32_SOLARIS
>>>>>>>=20
>>>>>>> correct jmpbuf sizes for I386_SOLARIS, AMD64_SOLARIS
>>>>>>> notice again that jmpbuf is much much smaller than sigjmpbuf,
>>>>>>> and this is jmpbuf; specifically:
>>>>>>> I386_SOLARIS jmpbuf 40 bytes with 4 align
>>>>>>> AMD64_SOLARIS jmpbuf 64 bytes with 8 align
>>>>>>> I386_SOLARIS sigjmpbuf 512 bytes with 4 align
>>>>>>> AMD64_SOLARIS sigjmpbuf 1024 bytes with 8 align
>>>>>>>=20
>>>>>>> remove some level of heap allocation of calling conventions
>>>>>>>=20
>>>>>>> accept all calling conventions for all targets
>>>>>>> Only NT386 has calling conventions, and it *highly* likely
>>>>>>> the only target ever to have them, therefore the mechanism
>>>>>>> does not need to be further generalized. (MIPS32 has two
>>>>>>> ABIs, but those will probably be two targets)
>>>>>>> This might let us save some unnecessary forking of *.i3 files.
>>>>>>> The initialization here can be further streamlined.
>>>>>>>=20
>>>>>>> shrink SOLgnu/SOLsun from sigjmpbuf to jmpbuf
>>>>>>> I'm not sure we use this though since we have a stack walker.
>>>>>>> fix SPARC64_SOLARIS too to be smaller
>>>>>>>=20
>>>>>>> SPARC32_SOLARIS
>>>>>>> jmpbuf size: 48
>>>>>>> sigjmpbuf size: 76
>>>>>>> alignment: 4 4
>>>>>>>=20
>>>>>>> SPARC64_SOLARIS
>>>>>>> jmpbuf size: 96
>>>>>>> sigjmpbuf size: 152
>>>>>>> alignment: 8 8
>>>>>>=20
>>>>>=20
>>>>=20
>>> =20
>>
>>
>>--Apple-Mail-78-848772270
>>Content-Transfer-Encoding: quoted-printable
>>Content-Type: text/html;
>> charset=us-ascii
>>
>>>>-webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I =
>>think we can argue that a programmer should program around this using =
>>TRY...FINALLY (i.e., even if they used =
>>FloatMode).
So, I think we are safe with jmpbuf =
>>instead of sigjmpbuf.


>>>>color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; =
>>font-style: normal; font-variant: normal; font-weight: normal; =
>>letter-spacing: normal; line-height: normal; orphans: 2; text-align: =
>>auto; text-indent: 0px; text-transform: none; white-space: normal; =
>>widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; =
>>-webkit-border-vertical-spacing: 0px; =
>>-webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: =
>>auto; -webkit-text-stroke-width: 0; ">>>style=3D"border-collapse: separate; -webkit-border-horizontal-spacing: =
>>0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); =
>>font-family: Helvetica; font-size: 12px; font-style: normal; =
>>font-variant: normal; font-weight: normal; letter-spacing: normal; =
>>line-height: normal; -webkit-text-decorations-in-effect: none; =
>>text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; =
>>orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; ">>>style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; =
>>-webkit-line-break: after-white-space; ">>>style=3D"border-collapse: separate; -webkit-border-horizontal-spacing: =
>>0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); =
>>font-family: Helvetica; font-size: 12px; font-style: normal; =
>>font-variant: normal; font-weight: normal; letter-spacing: normal; =
>>line-height: normal; -webkit-text-decorations-in-effect: none; =
>>text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; =
>>orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; ">>>class=3D"Apple-style-span" style=3D"border-collapse: separate; =
>>-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: =
>>0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; =
>>font-style: normal; font-variant: normal; font-weight: normal; =
>>letter-spacing: normal; line-height: normal; =
>>-webkit-text-decorations-in-effect: none; text-indent: 0px; =
>>-webkit-text-size-adjust: auto; text-transform: none; orphans: 2; =
>>white-space: normal; widows: 2; word-spacing: 0px; ">>>class=3D"Apple-style-span" style=3D"border-collapse: separate; =
>>-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: =
>>0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; =
>>font-style: normal; font-variant: normal; font-weight: normal; =
>>letter-spacing: normal; line-height: normal; =
>>-webkit-text-decorations-in-effect: none; text-indent: 0px; =
>>-webkit-text-size-adjust: auto; text-transform: none; orphans: 2; =
>>white-space: normal; widows: 2; word-spacing: 0px; ">>>class=3D"Apple-style-span" style=3D"border-collapse: separate; =
>>-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: =
>>0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; =
>>font-style: normal; font-variant: normal; font-weight: normal; =
>>letter-spacing: normal; line-height: normal; =
>>-webkit-text-decorations-in-effect: none; text-indent: 0px; =
>>-webkit-text-size-adjust: auto; text-transform: none; orphans: 2; =
>>white-space: normal; widows: 2; word-spacing: 0px; ">>>class=3D"Apple-style-span" style=3D"border-collapse: separate; =
>>-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: =
>>0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; =
>>font-style: normal; font-variant: normal; font-weight: normal; =
>>letter-spacing: normal; line-height: normal; =
>>-webkit-text-decorations-in-effect: none; text-indent: 0px; =
>>-webkit-text-size-adjust: auto; text-transform: none; orphans: 2; =
>>white-space: normal; widows: 2; word-spacing: 0px; ">>>class=3D"Apple-style-span" style=3D"border-collapse: separate; =
>>-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: =
>>0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; =
>>font-style: normal; font-variant: normal; font-weight: normal; =
>>letter-spacing: normal; line-height: normal; =
>>-webkit-text-decorations-in-effect: none; text-indent: 0px; =
>>-webkit-text-size-adjust: auto; text-transform: none; orphans: 2; =
>>white-space: normal; widows: 2; word-spacing: 0px; ">>>class=3D"Apple-style-span" style=3D"border-collapse: separate; =
>>-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: =
>>0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; =
>>font-style: normal; font-variant: normal; font-weight: normal; =
>>letter-spacing: normal; line-height: normal; =
>>-webkit-text-decorations-in-effect: none; text-indent: 0px; =
>>-webkit-text-size-adjust: auto; text-transform: none; orphans: 2; =
>>white-space: normal; widows: 2; word-spacing: 0px; ">>>class=3D"Apple-style-span" style=3D"border-collapse: separate; =
>>-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: =
>>0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; =
>>font-style: normal; font-variant: normal; font-weight: normal; =
>>letter-spacing: normal; line-height: normal; =
>>-webkit-text-decorations-in-effect: none; text-indent: 0px; =
>>-webkit-text-size-adjust: auto; text-transform: none; orphans: 2; =
>>white-space: normal; widows: 2; word-spacing: 0px; ">>>class=3D"Apple-style-span" color=3D"#0000FF">>>class=3D"Apple-style-span" face=3D"Gill Sans">>>class=3D"Apple-style-span" style=3D"color: rgb(0, 0, 255); font-family: =
>>'Gill Sans'; ">>>0, 255); font-family: 'Gill Sans'; ">Antony =
>>Hosking>>face=3D"Gill Sans">>>'Gill Sans'; ">>>'Gill Sans'; "> |>>class=3D"Apple-converted-space"> >>class=3D"Apple-style-span" style=3D"font-family: 'Gill Sans'; ">>>class=3D"Apple-style-span" style=3D"font-family: 'Gill Sans'; =
>>">Associate Professor>>style=3D"font-family: 'Gill Sans'; ">>>style=3D"font-family: 'Gill Sans'; "> | Computer Science | Purdue =
>>University>> face=3D"GillSans-Light">>>style=3D"font-family: GillSans-Light; ">305 N. University Street | West =
>>Lafayette | IN 47907 | USA>>class=3D"Apple-style-span" color=3D"#0000FF" face=3D"Gill Sans">>>class=3D"Apple-style-span" style=3D"color: rgb(0, 0, 255); font-family: =
>>'Gill Sans'; ">>>0, 255); font-family: 'Gill Sans'; ">Office>>class=3D"Apple-style-span" face=3D"GillSans-Light">>>class=3D"Apple-style-span" style=3D"font-family: GillSans-Light; ">>>class=3D"Apple-style-span" style=3D"font-family: GillSans-Light; =
>>"> +1 765 494 6001 |>>class=3D"Apple-converted-space"> >>class=3D"Apple-style-span" color=3D"#0000FF" face=3D"Gill Sans">>>class=3D"Apple-style-span" style=3D"color: rgb(0, 0, 255); font-family: =
>>'Gill Sans'; ">>>0, 255); font-family: 'Gill Sans'; ">Mobile>>class=3D"Apple-style-span" face=3D"GillSans-Light">>>class=3D"Apple-style-span" style=3D"font-family: GillSans-Light; ">>>class=3D"Apple-style-span" style=3D"font-family: GillSans-Light; ">>>class=3D"Apple-converted-space"> +1 765 427 =
>>5484>>face=3D"GillSans-Light">
>>class=3D"khtml-block-placeholder">
>>>
>>class=3D"Apple-interchange-newline">
>>class=3D"Apple-interchange-newline">
>>
>>
On 8 May 2010, at 18:56, Jay K wrote:
>>class=3D"Apple-interchange-newline">
Is =
>>"proper" saving/restoring as much as we can think of, or is it fast, or =
>>is it matching Ada and C++, or .. ?
Ada and C++ (gnat and g++) have =
>>often/historically used setjmp/longjmp.
  configure =
>>-enable-sjlj-exceptions
It might be interesting to see if they try to =
>>avoid the signal mask versions when they use setjmp/longjmp.
Lately =
>>they use table-based unwinding on platforms that they can -- which is to =
>>say, I *really* doubt
they save/restore the signal mask, but they =
>>might.


 - =
>>Jay

----------------------------------------
>>type=3D"cite">Subject: Re: [M3commit] CVS Update: =
>>cm3
From:>>href=3D"mailto:hosking at cs.purdue.edu">hosking at cs.purdue.edu

>>quote>Date: Sat, 8 May 2010 18:51:18 =
>>-0400
CC:>>href=3D"mailto:jkrell at elego.de">jkrell at elego.de;>>href=3D"mailto:m3commit at elegosoft.com">m3commit at elegosoft.com

>>ckquote>To:>>href=3D"mailto:jay.krell at cornell.edu">jay.krell at cornell.edu

>>quote>
>>type=3D"cite">
>>type=3D"cite">
On 8 May 2010, =
>>at 18:38, Jay K wrote:
>>type=3D"cite">
>>type=3D"cite">Or, understood, you really think we might throw around a =
>>signal mask change?
>>type=3D"cite">
It's =
>>possible.
>>type=3D"cite">
>>type=3D"cite">Realize also that sigsetjmp or setjmp, whichever we use, =
>>is called incredibly often, and sigsetjmp is =
>>likely
>>type=3D"cite">much much slower. Also notice..this I'll have to =
>>check...have we ever called =
>>sigsetjmp?
>>type=3D"cite">Well, no, I doubt it. But maybe =
>>setjmp vs. _setjmp.
>>type=3D"cite">Again though, this can be =
>>significantly slow.
>>type=3D"cite">>>type=3D"cite">
>>type=3D"cite">>>type=3D"cite">
>>type=3D"cite">Ultimately as well...see..I =
>>started this email without a firm opinion, but now I'm "firming" toward =
>>the change I made.
>>type=3D"cite">Consider C++ exceptions. =
>>Consider libunwind. Consider the SPARC stack walker (which I have to =
>>look at).
>>type=3D"cite">Do they save/restore signal =
>>masks? I doubt it. Maybe. We can look into it. But I doubt =
>>it.
>>type=3D"cite">
We should =
>>confirm.
>>type=3D"cite">
>>type=3D"cite">Raising an exception can indeed by slow. But entering a =
>>function with finally (or destructors) should not be overly =
>>so.
>>type=3D"cite">
Ultimately, we =
>>should use proper stack unwinding wherever =
>>possible.
>>type=3D"cite">
>>type=3D"cite">
>>type=3D"cite">>>type=3D"cite">
>>type=3D"cite">- =
>>Jay
>>type=3D"cite">
>>type=3D"cite">>>type=3D"cite">----------------------------------------

>>lockquote>>>type=3D"cite">From:>>href=3D"mailto:hosking at cs.purdue.edu">hosking at cs.purdue.edu

>>quote>>>type=3D"cite">Date: Sat, 8 May 2010 18:28:36 =
>>-0400
>>type=3D"cite">To:>>href=3D"mailto:jkrell at elego.de">jkrell at elego.de

>>kquote>>>type=3D"cite">CC:>>href=3D"mailto:m3commit at elegosoft.com">m3commit at elegosoft.com

>>ckquote>>>type=3D"cite">Subject: Re: [M3commit] CVS =
>>Update: cm3
>>type=3D"cite">>>type=3D"cite">
>>type=3D"cite">Ah, =
>>now I remember. sigjmpbuf is important for unwinding on exception to =
>>make sure that if we unwind through a frame where the programmer changed =
>>the signal mask that we also restore the signal mask of the caller. I =
>>think you also probably break things like FloatMode by not restoring the =
>>signal mask =
>>properly.
>>type=3D"cite">>>type=3D"cite">
>>type=3D"cite">On 9 =
>>May 2010, at 00:09, Jay Krell =
>>wrote:
>>type=3D"cite">>>type=3D"cite">
>>type=3D"cite">>>type=3D"cite">CVSROOT: =
>>/usr/cvs

>>e type=3D"cite">>>type=3D"cite">Changes by: jkrell at birch. =
>>10/05/09 =
>>00:09:58

>>e type=3D"cite">>>type=3D"cite">>>type=3D"cite">

>>ckquote type=3D"cite">>>type=3D"cite">Modified =
>>files:
>>type=3D"cite">>>type=3D"cite">cm3/m3-sys/m3middle/src/: =
>>Target.i3 =
>>Target.m3

>>te type=3D"cite">>>type=3D"cite">>>type=3D"cite">

>>ckquote type=3D"cite">>>type=3D"cite">Log =
>>message:

>>e type=3D"cite">>>type=3D"cite">add =
>>SPARC32_SOLARIS

>>ockquote type=3D"cite">>>type=3D"cite">>>type=3D"cite">

>>ckquote type=3D"cite">>>type=3D"cite">correct jmpbuf sizes for =
>>I386_SOLARIS, =
>>AMD64_SOLARIS

>>kquote type=3D"cite">>>type=3D"cite">notice again that jmpbuf is much =
>>much smaller than =
>>sigjmpbuf,

>>ote type=3D"cite">>>type=3D"cite">and this is jmpbuf; =
>>specifically:

>>kquote type=3D"cite">>>type=3D"cite">I386_SOLARIS jmpbuf 40 bytes =
>>with 4 =
>>align
>>type=3D"cite">>>type=3D"cite">AMD64_SOLARIS jmpbuf 64 bytes =
>>with 8 =
>>align
>>type=3D"cite">>>type=3D"cite">I386_SOLARIS sigjmpbuf 512 bytes =
>>with 4 =
>>align
>>type=3D"cite">>>type=3D"cite">AMD64_SOLARIS sigjmpbuf 1024 =
>>bytes with 8 =
>>align
>>type=3D"cite">>>type=3D"cite">>>type=3D"cite">

>>ckquote type=3D"cite">>>type=3D"cite">remove some level of heap =
>>allocation of calling =
>>conventions

>>uote type=3D"cite">>>type=3D"cite">>>type=3D"cite">

>>ckquote type=3D"cite">>>type=3D"cite">accept all calling conventions =
>>for all =
>>targets

>> type=3D"cite">>>type=3D"cite">Only NT386 has calling =
>>conventions, and it *highly* =
>>likely
>>type=3D"cite">>>type=3D"cite">the only target ever to have =
>>them, therefore the =
>>mechanism

>>te type=3D"cite">>>type=3D"cite">does not need to be further =
>>generalized. (MIPS32 has =
>>two
>>type=3D"cite">>>type=3D"cite">ABIs, but those will probably be =
>>two =
>>targets)

>>e type=3D"cite">>>type=3D"cite">This might let us save some =
>>unnecessary forking of *.i3 =
>>files.
>>type=3D"cite">>>type=3D"cite">The initialization here can be =
>>further =
>>streamlined.

>>quote type=3D"cite">>>type=3D"cite">>>type=3D"cite">

>>ckquote type=3D"cite">>>type=3D"cite">shrink SOLgnu/SOLsun from =
>>sigjmpbuf to =
>>jmpbuf
>>type=3D"cite">>>type=3D"cite">I'm not sure we use this though =
>>since we have a stack =
>>walker.

>> type=3D"cite">>>type=3D"cite">fix SPARC64_SOLARIS too to be =
>>smaller

>> type=3D"cite">>>type=3D"cite">>>type=3D"cite">

>>ckquote type=3D"cite">>>type=3D"cite">>>type=3D"cite">SPARC32_SOLARIS
>>blockquote>
>> type=3D"cite">jmpbuf size: =
>>48
>>type=3D"cite">>>type=3D"cite">sigjmpbuf size: =
>>76
>>type=3D"cite">>>type=3D"cite">alignment: 4 =
>>4
>>type=3D"cite">>>type=3D"cite">>>type=3D"cite">

>>ckquote type=3D"cite">>>type=3D"cite">>>type=3D"cite">SPARC64_SOLARIS
>>blockquote>
>> type=3D"cite">jmpbuf size: =
>>96
>>type=3D"cite">>>type=3D"cite">sigjmpbuf size: =
>>152
>>type=3D"cite">>>type=3D"cite">alignment: 8 =
>>8
>>type=3D"cite">>>type=3D"cite">
>>type=3D"cite">>>type=3D"cite">
>>type=3D"cite">
>>style=3D"white-space:pre">>>style=3D"white-space:pre"> >>style=3D"white-space:pre">    >>class=3D"Apple-tab-span" style=3D"white-space:pre">>>class=3D"Apple-tab-span" style=3D"white-space:pre">  =
>> 

=
>>
>>--Apple-Mail-78-848772270--
 		 	   		  


More information about the M3devel mailing list