caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Safe Obj.magic container ?
@ 2008-02-27  9:09 David Teller
  2008-02-27  9:43 ` [Caml-list] " Luc Maranget
  2008-02-27 11:23 ` Tom Primožič
  0 siblings, 2 replies; 11+ messages in thread
From: David Teller @ 2008-02-27  9:09 UTC (permalink / raw)
  To: Caml

   Along the lines of this discussion on Obj.magic, I have a question
about the semantics of the beast. 

 Assuming that I have two types t and u and a value v of type t, under
which conditions on t and u is it safe to Obj.magic v to type u, pass u
around a few times and Obj.magic it back to type t ? 


In particular
1. can I assume that this is always going to work if u is 'a.'a   ?

2. if t is a polymorphic variant written inline without a type name, can
I assume that if I write the same inline definition in another module,
it will have the same internal representation ?

3. assuming the answer to 1. is No, is there a type u or a simple
manipulation which should work for any type t ? Or perhaps just for
polymorphic variants ?

My guesses are 
1. No
2. Yes
3. Possibly if I restrict myself to polymorphic variants. Otherwise,
perhaps by playing with Deriving's Typeable.

Thanks,
 David
-- 
David Teller
 Security of Distributed Systems
  http://www.univ-orleans.fr/lifo/Members/David.Teller
 Angry researcher: French Universities need reforms, but the LRU act brings liquidations. 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Safe Obj.magic container ?
  2008-02-27  9:09 Safe Obj.magic container ? David Teller
@ 2008-02-27  9:43 ` Luc Maranget
       [not found]   ` <37B36607-9F22-4537-B4DB-1E04348E2B90@inria.fr>
  2008-02-27 11:23 ` Tom Primožič
  1 sibling, 1 reply; 11+ messages in thread
From: Luc Maranget @ 2008-02-27  9:43 UTC (permalink / raw)
  To: David Teller; +Cc: Caml

>    Along the lines of this discussion on Obj.magic, I have a question
> about the semantics of the beast. 

I have not followed the discussion, but here are a few clues

The semantics of Obj.magic is as follows:

1. Obj.magic does not exist. Don't use it.

2. Obj.magic is black magic, you can see it as the identity
   (fun x -> x)  with type 'a -> 'b.

As I see it, 2. steems from the uniform representation of values by OCaml.

A value is either a scalar, or a pointer, and this can be tested
dynamically (by looking at the low order bit) by
Obj.is_int/Obj.is_block.



-- 
Luc


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Safe Obj.magic container ?
  2008-02-27  9:09 Safe Obj.magic container ? David Teller
  2008-02-27  9:43 ` [Caml-list] " Luc Maranget
@ 2008-02-27 11:23 ` Tom Primožič
  2008-02-27 21:22   ` David Teller
  1 sibling, 1 reply; 11+ messages in thread
From: Tom Primožič @ 2008-02-27 11:23 UTC (permalink / raw)
  To: David Teller; +Cc: Caml

[-- Attachment #1: Type: text/plain, Size: 780 bytes --]

The following are my experience and guesses, nothing
scientific/official/thoroughly tested:

> 1. can I assume that this is always going to work if u is 'a.'a   ?


Well, there is no type 'a.'a. You can have:
type u = { everything: 'a . 'a }
but this presupposes that values of type u are blocks (heap-allocated).
Therefore, if you cast a boolean (true) to type u, and then try to access
the everything field of the "new" value, you will get a segfault.

3. assuming the answer to 1. is No, is there a type u or a simple
> manipulation which should work for any type t ? Or perhaps just for
> polymorphic variants ?
>

type u = int
this will work for any type. You can even do pointer manipulation with it
(adding and subtracting even numbers of bytes).

Sorry everybody.

 - Tom

[-- Attachment #2: Type: text/html, Size: 1219 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Safe Obj.magic container ?
  2008-02-27 11:23 ` Tom Primožič
@ 2008-02-27 21:22   ` David Teller
  0 siblings, 0 replies; 11+ messages in thread
From: David Teller @ 2008-02-27 21:22 UTC (permalink / raw)
  To: Tom Primožič; +Cc: Caml


On Wed, 2008-02-27 at 12:23 +0100, Tom Primožič wrote:
> The following are my experience and guesses, nothing
> scientific/official/thoroughly tested:
>         1. can I assume that this is always going to work if u is
>         'a.'a   ?
> 
> Well, there is no type 'a.'a. You can have:
> type u = { everything: 'a . 'a }

That's actually what I meant.

> but this presupposes that values of type u are blocks
> (heap-allocated). Therefore, if you cast a boolean (true) to type u,
> and then try to access the everything field of the "new" value, you
> will get a segfault.

Ok.

> 
>         3. assuming the answer to 1. is No, is there a type u or a
>         simple
>         manipulation which should work for any type t ? Or perhaps
>         just for
>         polymorphic variants ?
> 
> type u = int
> this will work for any type. You can even do pointer manipulation with
> it (adding and subtracting even numbers of bytes).
>
> Sorry everybody.

Er... I can't quite figure if it's a joke.

>  - Tom

Cheers,
 David

-- 
David Teller
 Security of Distributed Systems
  http://www.univ-orleans.fr/lifo/Members/David.Teller
 Angry researcher: French Universities need reforms, but the LRU act brings liquidations. 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Safe Obj.magic container ?
       [not found]   ` <37B36607-9F22-4537-B4DB-1E04348E2B90@inria.fr>
@ 2008-02-28 14:23     ` Damien Doligez
  2008-02-28 15:29       ` David Teller
  2008-02-28 19:20       ` Jake Donham
  0 siblings, 2 replies; 11+ messages in thread
From: Damien Doligez @ 2008-02-28 14:23 UTC (permalink / raw)
  To: caml users

On 2008-02-27, at 10:43, Luc Maranget wrote:

> The semantics of Obj.magic is as follows:
>
> 1. Obj.magic does not exist. Don't use it.
>
> 2. Obj.magic is black magic, you can see it as the identity
>  (fun x -> x)  with type 'a -> 'b.
>
> As I see it, 2. steems from the uniform representation of values by  
> OCaml.
>
> A value is either a scalar, or a pointer, and this can be tested
> dynamically (by looking at the low order bit) by
> Obj.is_int/Obj.is_block.


If that was the whole story, Obj.magic would be pretty safe.  But
there are exceptions to the uniform representation of values, and
they make Obj.magic really hard to use.

The most important exception is floating-point numbers.  They are
not always represented as one word each, and that means even
Obj.repr is unsafe.

Example (on a 32-bit machine):

        Objective Caml version 3.10.2+rc1

# let x = Obj.repr 1;;
val x : Obj.t = <abstr>
# let y = Obj.repr 1.0;;
val y : Obj.t = <abstr>
# [| x; y |];;
- : Obj.t array = [|<abstr>; <abstr>|]
# [| y; x |];;
Bus error

My advice: don't use the Obj module if you were surprised by this
example.

-- Damien


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Safe Obj.magic container ?
  2008-02-28 14:23     ` Damien Doligez
@ 2008-02-28 15:29       ` David Teller
  2008-02-28 16:24         ` Damien Doligez
  2008-02-29  1:52         ` Jacques Garrigue
  2008-02-28 19:20       ` Jake Donham
  1 sibling, 2 replies; 11+ messages in thread
From: David Teller @ 2008-02-28 15:29 UTC (permalink / raw)
  To: Damien Doligez; +Cc: caml users

Interesting. Can I assume that, if my type is boxed (in this case, a
polymorphic variant), I can successfully convert it to Obj.t and back ?

Thanks,
 David

On Thu, 2008-02-28 at 15:23 +0100, Damien Doligez wrote:
> If that was the whole story, Obj.magic would be pretty safe.  But
> there are exceptions to the uniform representation of values, and
> they make Obj.magic really hard to use.
> 
> The most important exception is floating-point numbers.  They are
> not always represented as one word each, and that means even
> Obj.repr is unsafe.

-- 
David Teller
 Security of Distributed Systems
  http://www.univ-orleans.fr/lifo/Members/David.Teller
 Angry researcher: French Universities need reforms, but the LRU act brings liquidations. 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Safe Obj.magic container ?
  2008-02-28 15:29       ` David Teller
@ 2008-02-28 16:24         ` Damien Doligez
  2008-02-29  1:52         ` Jacques Garrigue
  1 sibling, 0 replies; 11+ messages in thread
From: Damien Doligez @ 2008-02-28 16:24 UTC (permalink / raw)
  To: caml users; +Cc: David Teller


On 2008-02-28, at 16:29, David Teller wrote:

> Interesting. Can I assume that, if my type is boxed (in this case, a
> polymorphic variant), I can successfully convert it to Obj.t and  
> back ?


I don't know enough about the representation of polymorphic variants to
give an authoritative answer.

-- Damien


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Safe Obj.magic container ?
  2008-02-28 14:23     ` Damien Doligez
  2008-02-28 15:29       ` David Teller
@ 2008-02-28 19:20       ` Jake Donham
  2008-02-28 23:19         ` Richard Jones
  1 sibling, 1 reply; 11+ messages in thread
From: Jake Donham @ 2008-02-28 19:20 UTC (permalink / raw)
  To: caml users

[-- Attachment #1: Type: text/plain, Size: 401 bytes --]

On Thu, Feb 28, 2008 at 6:23 AM, Damien Doligez <damien.doligez@inria.fr>
wrote:

> Example (on a 32-bit machine):
>
>        Objective Caml version 3.10.2+rc1
>
> # let x = Obj.repr 1;;
> val x : Obj.t = <abstr>
> # let y = Obj.repr 1.0;;
> val y : Obj.t = <abstr>
> # [| x; y |];;
> - : Obj.t array = [|<abstr>; <abstr>|]
> # [| y; x |];;
> Bus error


Could you please explain this behavior?

Jake

[-- Attachment #2: Type: text/html, Size: 721 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Safe Obj.magic container ?
  2008-02-28 19:20       ` Jake Donham
@ 2008-02-28 23:19         ` Richard Jones
  0 siblings, 0 replies; 11+ messages in thread
From: Richard Jones @ 2008-02-28 23:19 UTC (permalink / raw)
  To: Jake Donham; +Cc: caml users

On Thu, Feb 28, 2008 at 11:20:53AM -0800, Jake Donham wrote:
> On Thu, Feb 28, 2008 at 6:23 AM, Damien Doligez <damien.doligez@inria.fr>
> wrote:
> 
> > Example (on a 32-bit machine):
> >
> >        Objective Caml version 3.10.2+rc1
> >
> > # let x = Obj.repr 1;;
> > val x : Obj.t = <abstr>
> > # let y = Obj.repr 1.0;;
> > val y : Obj.t = <abstr>
> > # [| x; y |];;
> > - : Obj.t array = [|<abstr>; <abstr>|]
> > # [| y; x |];;
> > Bus error
> 
> 
> Could you please explain this behavior?

I _think_ this is what's going on:

Obj.repr is just the %identity primitive.  So 'x' and 'y' still look
like an int and a float respectively to the garbage collector.
ie. 'x' is still shifted left 1 place with the bottom bit set.  'y' is
still a pointer to a boxed 8 bit float (with a header on the heap
identifying it as such).

Constructing the array calls the caml_make_array primitive, which
looks at the tag of the first element to see if it's a float.  This
would cause the unboxing optimization.

Unfortunately if caml_make_array spots the possible unboxing of an
array of floats, then it blindly copies the remaining elements, which
dereferences the int (thinking it's a pointer to a float) and that
causes the segfault.

This also explains why it works the other way around, because having
the int first doesn't trigger the optimization.

Rich.

-- 
Richard Jones
Red Hat


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Safe Obj.magic container ?
  2008-02-28 15:29       ` David Teller
  2008-02-28 16:24         ` Damien Doligez
@ 2008-02-29  1:52         ` Jacques Garrigue
  2008-02-29  8:18           ` David Teller
  1 sibling, 1 reply; 11+ messages in thread
From: Jacques Garrigue @ 2008-02-29  1:52 UTC (permalink / raw)
  To: David.Teller; +Cc: caml-list

From: David Teller <David.Teller@univ-orleans.fr>

> Interesting. Can I assume that, if my type is boxed (in this case, a
> polymorphic variant), I can successfully convert it to Obj.t and back ?

Yes : polymorphic variants are either ints or normal blocks, so this
should work. This is also true for normal variants. Actually I don't
know of any non-uniform representation problem outside of floats.

Note however that this problem of non-uniform representation is no the
only danger when using Obj.magic imprudently. I recall another problem
with functional values. I'm afraid only Xavier could explain that one.

If you have only (polymorphic) variants, and if you keep the types
monomorphic (i.e. always add complete type annotations to Obj.magic or
Obj.obj), things should work properly in the current implementation.

Of course you should limit that kind of uses to things like
persistant storage or C interfaces, where you have to go through an
untyped world anyway, and avoid it at all costs in plain ml programs.

Jacques Garrigue


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Safe Obj.magic container ?
  2008-02-29  1:52         ` Jacques Garrigue
@ 2008-02-29  8:18           ` David Teller
  0 siblings, 0 replies; 11+ messages in thread
From: David Teller @ 2008-02-29  8:18 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: caml-list

Thanks for the clarification. Again, I only have polymorphic variants,
no functions, no floats, no lazy values, etc. 

The reason why I need to go through some Obj conversion is essentially
the same reason safe marshalling needs to go through that conversion:
storing typed information on an untyped medium (or, in this case,
polymorphically typed information on a non-polymorphically typed medium)
-- along with a type certificate. It just happens that this
less-richly-typed medium is an exception.

Cheers,
 David

P.S.:
 I have tried alternative solutions but the best I can come up with
involves something like 30% slowdown on my testsuite. Which is a bit too
much for something which is supposed to be speed-critical.

On Fri, 2008-02-29 at 10:52 +0900, Jacques Garrigue wrote:
> From: David Teller <David.Teller@univ-orleans.fr>
> 
> > Interesting. Can I assume that, if my type is boxed (in this case, a
> > polymorphic variant), I can successfully convert it to Obj.t and back ?
> 
> Yes : polymorphic variants are either ints or normal blocks, so this
> should work. This is also true for normal variants. Actually I don't
> know of any non-uniform representation problem outside of floats.
> 
> Note however that this problem of non-uniform representation is no the
> only danger when using Obj.magic imprudently. I recall another problem
> with functional values. I'm afraid only Xavier could explain that one.
> 
> If you have only (polymorphic) variants, and if you keep the types
> monomorphic (i.e. always add complete type annotations to Obj.magic or
> Obj.obj), things should work properly in the current implementation.
> 
> Of course you should limit that kind of uses to things like
> persistant storage or C interfaces, where you have to go through an
> untyped world anyway, and avoid it at all costs in plain ml programs.
> 
> Jacques Garrigue
> 
-- 
David Teller
 Security of Distributed Systems
  http://www.univ-orleans.fr/lifo/Members/David.Teller
 Angry researcher: French Universities need reforms, but the LRU act brings liquidations. 


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2008-02-29  8:18 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-27  9:09 Safe Obj.magic container ? David Teller
2008-02-27  9:43 ` [Caml-list] " Luc Maranget
     [not found]   ` <37B36607-9F22-4537-B4DB-1E04348E2B90@inria.fr>
2008-02-28 14:23     ` Damien Doligez
2008-02-28 15:29       ` David Teller
2008-02-28 16:24         ` Damien Doligez
2008-02-29  1:52         ` Jacques Garrigue
2008-02-29  8:18           ` David Teller
2008-02-28 19:20       ` Jake Donham
2008-02-28 23:19         ` Richard Jones
2008-02-27 11:23 ` Tom Primožič
2008-02-27 21:22   ` David Teller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).