Re: move object from heap to stack

2012-09-20 Thread monarch_dodra

On Wednesday, 19 September 2012 at 21:36:56 UTC, Namespace wrote:

I count it to destroy it if it isn't used anymore.
What I'm saying though is that when your stacked_obj goes out 
of scope, it gets destroyed, 100% of the time. The chunk 
disappears, along with any object inside it. When that happens, 
it doesn't matter what the count is, whatever is inside chunk 
MUST be destroyed.


I can remove this behaviour but IMO with this you haven't 
unnecessary use of stack memory. Am I wrong?
Yes, because all your stacked_obj have a chunk member variable. 
The reference count doesn't change that. When you pass by value, 
a new chunk is created an copied.


Your postblit is weird:
this(this) {
this._use_counter++;
this._use_counter = _use_counter;
}
The way postblit works is that first, the other is memcopyed 
onto this. Then, postblit modifies the current object. 
this._use_counter = _use_counter; makes no sense.


One more thing: You can't memcopy a class from one place to 
another, because you don't know if it has a CC or not. You 
*could* swap the class, which would be safe for the class itself, 
but not for anything else referencing the class.


Furthermore, if I copy the stack object e.g. if I pass it as 
value parameter to another function/class, I can store it as 
long as it's needed. Maybe that should be the task of the heap, 
but I'm not sure.

Yes, but technically, you are still passing a copy.

Anyways, I re-read scoped's implementation, and classes ARE 
allocated on the stack. Further more, they can emplace their new 
object.


They can also copy an existing class into them... provided the 
class gives access to CC. It is not a move, but, IMO, a move 
would be unsafe anyways.


import std.typecons;

class A
{
this(){}
this(int){}
this(A){}
}

void main()
{
auto sa = scoped!A(new A());
auto sb = scoped!A(5);
}

I'm not entirely.


Re: move object from heap to stack

2012-09-20 Thread monarch_dodra

On Thursday, 20 September 2012 at 08:10:36 UTC, Namespace wrote:

You're right.
This is my next try: http://dpaste.dzfl.pl/02b32d33
Do you have anything else to say? :)


I think it looks good, but I'm unsure about move, or allowing 
pass by value:


Classes can't be memcopied the way structs can: Class may have 
default constructors, or copy constructors, which would be 
totally ignored by a memcopy. For example, if your class had a 
RefCounted member, its postblit would never be called, and it 
would then be over destroyed:



class A
{
RefCounted!int rf;
this()
{
rf.RefCounted.ensureInitialized();
rf = 5;
}
}

void main()
{
A a = new A();
OnStack!A osa = OnStack!A.move(a);
}

core.exception.InvalidMemoryOperationError

Here, osa makes a binary copy of the RefCounted, so the count 
stays at 1.

Then, when osa is destroyed, it deletes the RefCounted's store.
However, when a is destroyed, it still has a pointer to the 
(deleted) store, creating the Error...


I think move has to go, because classes are just not moveable. 
pass by value can stay, if and only if, T gives a copy 
constructor. Or NO constructors (in which case a memcopy should 
be the same as a default copy).


Re: move object from heap to stack

2012-09-20 Thread Johannes Pfau
Am Thu, 20 Sep 2012 10:11:37 +0200
schrieb Namespace rswhi...@googlemail.com:

 You're right.
 This is my next try: http://dpaste.dzfl.pl/02b32d33
 Do you have anything else to say? :)

I think it shouldn't be possible to copy an OnStack struct. The
destructor is run for every copy, but the constructor was run only
once. So if a class keeps external references (e.g. file handles) and
closes those handles in the destructor, making a copy would result
in the destructor running twice and therefore closing the same handle
twice.

I think the usage of a OnStack struct must be quite limited to be safe:

{
auto a = OnStack!(A)(); //allocate in scope
a.doSomething(); //Calling members is fine
//a.get and a must not escape this scope (I guess we can't guarantee
//that without compiler help?)

//passing a.get to a function is valid, as long as the function
//doesn't keep a reference (the function parameter must be marked
//with scope)
someMethod(a.get);
//As a shouldn't be copied, an OnStack can't be passed to another
//function.

//no copies for OnStack allowed
//destroy at end of scope
}

Those rules are pretty strict, but maybe that's the only way to have a
safe OnStack. Maybe I forgot some detail and those rules aren't even
strict enough.


Re: move object from heap to stack

2012-09-20 Thread Johannes Pfau
Am Thu, 20 Sep 2012 12:06:28 +0200
schrieb monarch_dodra monarchdo...@gmail.com:

 On Thursday, 20 September 2012 at 08:10:36 UTC, Namespace wrote:
  You're right.
  This is my next try: http://dpaste.dzfl.pl/02b32d33
  Do you have anything else to say? :)
 
 I think it looks good, but I'm unsure about move, or allowing 
 pass by value:
 
 Classes can't be memcopied the way structs can: Class may have 
 default constructors, or copy constructors, which would be 
 totally ignored by a memcopy. For example, if your class had a 
 RefCounted member, its postblit would never be called, and it 
 would then be over destroyed:
 
 
 class A
 {
  RefCounted!int rf;
  this()
  {
  rf.RefCounted.ensureInitialized();
  rf = 5;
  }
 }
 
 void main()
 {
  A a = new A();
  OnStack!A osa = OnStack!A.move(a);
 }
 
 core.exception.InvalidMemoryOperationError
 
 Here, osa makes a binary copy of the RefCounted, so the count 
 stays at 1.
 Then, when osa is destroyed, it deletes the RefCounted's store.
 However, when a is destroyed, it still has a pointer to the 
 (deleted) store, creating the Error...
 
 I think move has to go, because classes are just not moveable. 
 pass by value can stay, if and only if, T gives a copy 
 constructor. Or NO constructors (in which case a memcopy should 
 be the same as a default copy).

http://dlang.org/struct.html
D classes do not really have copy constructors. You could assume that
if a constructor has only one argument and it's of the same type as the
class, it's a copy constructor. But that's a pure convention then,
nothing than could be enforced in any way. Copying classes is
dangerous, and problems can also happen without constructors:

--
class A
{
void* handle;

~this()
{
if(handle)
free(handle);
}
}

{
auto a = OnStack!A();
a.handle = someHandle;
auto b = a; //copy
} //end of scope, someHandle is freed twice
--

This can even happen if the class does not keep any reference types.
The example would also be valid with a file handle (uint).



Re: move object from heap to stack

2012-09-20 Thread Namespace
So I should disable the copy ctor (@disable this(this)) and drop 
move, right?
As you can See if I pass a OnStack to function/class i'm using 
.get all the Time. The only other method IMO would be to pass it 
as OnStack by value and Store it in the other class also as 
OnStack, right?


@bearophiole: just to Know if something lile this is possible.


Re: move object from heap to stack

2012-09-20 Thread monarch_dodra

On Thursday, 20 September 2012 at 12:32:03 UTC, Namespace wrote:
So I should disable the copy ctor (@disable this(this)) and 
drop move, right?
Yes, but at that point, what you have is scoped!T re-implemented 
:/


As you can See if I pass a OnStack to function/class i'm using 
.get all the Time.
You could alias get this. This way, your OnStack will call cast 
as a T implicitly. Again, this is what scoped!T does.


The only other method IMO would be to pass it as OnStack by 
value and Store it in the other class also as OnStack, right?


Yes, but that would require a copy contructor this(this), which 
we have actually ruled out. You can pass the T itself thanks to 
the implicit cast to T, but you can't pass an actual OnStack 
object.


Re: move object from heap to stack

2012-09-20 Thread Namespace
On Thursday, 20 September 2012 at 14:02:01 UTC, monarch_dodra 
wrote:

On Thursday, 20 September 2012 at 12:32:03 UTC, Namespace wrote:
So I should disable the copy ctor (@disable this(this)) and 
drop move, right?
Yes, but at that point, what you have is scoped!T 
re-implemented :/


As you can See if I pass a OnStack to function/class i'm using 
.get all the Time.
You could alias get this. This way, your OnStack will call 
cast as a T implicitly. Again, this is what scoped!T does.


The only other method IMO would be to pass it as OnStack by 
value and Store it in the other class also as OnStack, right?


Yes, but that would require a copy contructor this(this), 
which we have actually ruled out. You can pass the T itself 
thanks to the implicit cast to T, but you can't pass an actual 
OnStack object.


http://dpaste.dzfl.pl/edit/361a54eb
With
[code]
@disable this(this);
[/code]
this don't work (as expected). But with the copy ctor but without 
.get you earn a segmentation fault (as you can see). So you can 
disable the copy ctor but without using .get you're not get what 
you want. Even with scoped, but scoped's getter name is too long.


Re: move object from heap to stack

2012-09-20 Thread monarch_dodra

On Thursday, 20 September 2012 at 14:09:29 UTC, Namespace wrote:


http://dpaste.dzfl.pl/edit/361a54eb
With
[code]
@disable this(this);
[/code]
this don't work (as expected). But with the copy ctor but 
without .get you earn a segmentation fault (as you can see). 
So you can disable the copy ctor but without using .get you're 
not get what you want. Even with scoped, but scoped's getter 
name is too long.


Wrong link.


Re: move object from heap to stack

2012-09-20 Thread Namespace
On Thursday, 20 September 2012 at 14:15:23 UTC, monarch_dodra 
wrote:

On Thursday, 20 September 2012 at 14:09:29 UTC, Namespace wrote:


http://dpaste.dzfl.pl/edit/361a54eb
With
[code]
@disable this(this);
[/code]
this don't work (as expected). But with the copy ctor but 
without .get you earn a segmentation fault (as you can see). 
So you can disable the copy ctor but without using .get you're 
not get what you want. Even with scoped, but scoped's getter 
name is too long.


Wrong link.


Try this: http://dpaste.dzfl.pl/9247af54


Re: move object from heap to stack

2012-09-20 Thread monarch_dodra

On Thursday, 20 September 2012 at 15:04:48 UTC, Namespace wrote:
On Thursday, 20 September 2012 at 14:15:23 UTC, monarch_dodra 
wrote:
On Thursday, 20 September 2012 at 14:09:29 UTC, Namespace 
wrote:



http://dpaste.dzfl.pl/edit/361a54eb
With
[code]
@disable this(this);
[/code]
this don't work (as expected). But with the copy ctor but 
without .get you earn a segmentation fault (as you can 
see). So you can disable the copy ctor but without using .get 
you're not get what you want. Even with scoped, but scoped's 
getter name is too long.


Wrong link.


Try this: http://dpaste.dzfl.pl/9247af54


What did you expect? You are passing your OnStack by value. In 
this particular case, you are over destroying your OnStack!B, 
which in turn over destroyes his _a.


Reactivate the disable, and you'll see the problem blatantly:
http://dpaste.dzfl.pl/9e873033
/home/c192/c104.d(102): Error: struct c104.OnStack!(A).OnStack is 
not copyable because it is annotated with @disable


The problem with implicit cast is that *sometimes* you think it 
does it, but in fact, it doesn't. Here, it didn't.


The opCall expects Arg... so if you give it an OnStack, it 
accepts an OnStack. If you want it to take a T, you have to 
specify it, either in the template, or with get, or with a cast.


Here is a cast version, with this(this) disabled:
http://dpaste.dzfl.pl/837f44a9


Re: move object from heap to stack

2012-09-20 Thread Namespace
I expect nothing, my only intention was to show you, that this 
cannot work. But that it works with an explicit cast is very 
impressive. I thought the alias this does it automatically.

I'm learning too. ;)


move object from heap to stack

2012-09-19 Thread Namespace

Is that possible?
I can initialize an object with scope or, in feature, with 
scoped, directly on the stack but is it also possible to move an 
existing object from the heap to the stack?


Re: move object from heap to stack

2012-09-19 Thread Namespace

On Wednesday, 19 September 2012 at 13:32:42 UTC, Namespace wrote:

Is that possible?
I can initialize an object with scope or, in feature, with 
scoped, directly on the stack but is it also possible to move 
an existing object from the heap to the stack?


I tried this:
http://dpaste.dzfl.pl/2955ff41
But as you can see in line 25/26, after I destroyed the heap 
object, the stack object seems to be corrupted.


Re: move object from heap to stack

2012-09-19 Thread Simen Kjaeraas
On Wed, 19 Sep 2012 15:45:21 +0200, Namespace rswhi...@googlemail.com  
wrote:



On Wednesday, 19 September 2012 at 13:32:42 UTC, Namespace wrote:

Is that possible?
I can initialize an object with scope or, in feature, with scoped,  
directly on the stack but is it also possible to move an existing  
object from the heap to the stack?


I tried this:
http://dpaste.dzfl.pl/2955ff41
But as you can see in line 25/26, after I destroyed the heap object, the  
stack object seems to be corrupted.


The problem here is that A.sizeof returns the size of the reference, not
the instance. Instead you should use __traits(classInstanceSize, A).

Also, do have a look at the internals of std.typecons.scoped, it likely
contains some good ideas.

--
Simen


Re: move object from heap to stack

2012-09-19 Thread Namespace

Thanks, I will use __traits(classInstanceSize, A);
But it does not work either.


Re: move object from heap to stack

2012-09-19 Thread Namespace
On Wednesday, 19 September 2012 at 17:08:28 UTC, monarch_dodra 
wrote:
On Wednesday, 19 September 2012 at 14:16:31 UTC, Namespace 
wrote:

Thanks, I will use __traits(classInstanceSize, A);
But it does not work either.


This is because classes are already pointers. when you write 
a, you are getting the address of pointer itself. So when 
you memcopy, don't use a, but use cast(void*)a.


What you were currently doing was memcopying the pointer to a 
into your chunk. From there, since you were casting to A*, 
everything worked and was legal, but you still only had 1 class 
intance. Your destroying that instance made your ap crash.


this works:
http://dpaste.dzfl.pl/8ba1f457


I forget this. Thank you!
IMO something like this should exist in phobos. A more flexible 
version of scoped also.


Re: move object from heap to stack

2012-09-19 Thread Namespace

Result:
http://dpaste.dzfl.pl/24988d8f


Re: move object from heap to stack

2012-09-19 Thread monarch_dodra

On Wednesday, 19 September 2012 at 19:24:34 UTC, Namespace wrote:

Result:
http://dpaste.dzfl.pl/24988d8f


I like it, but how can something placed on the stack be reference 
counted? The chunk is also placed on the stack, so it doesn't 
really make sense to me: When the object goes out of scope, the 
chunk goes, regardless of ref count. I think you should ditch the 
whole ref count thing.


You'll also have to be aware of the dangers of putting a class 
instance on the stack:


main()
{
A a;
{
stacked_obj!A so;
so.gen;
a = so.get;
}
a.print(); //-- undefined, with or without reference count
}

IE: Big red comment you should NEVER extract an instance from the 
stack.