YetAnotherForum
Welcome Guest Search | Active Topics | Log In | Register

[sq 3.0.2] closure cloned instead of assigned on derived class objects(works ok with baseless class)
nitramc
#1 Posted : Friday, August 03, 2012 9:08:27 PM(UTC)
Rank: Member

Groups: Registered
Joined: 3/1/2011(UTC)
Posts: 16
Location: Buenos Aires, Argentina

Thanks: 2 times
Was thanked: 0 time(s) in 0 post(s)
I was wondering why a new closure is created when assigning a derived class' function but not when assigning a base.
As you can see in the output below, each assignment creates a new pointer.

I need to change functions during execution, but only if they match the old one.

Code:
Code:


class A {
    function memberfn() { }
}

class D extends A {
    function memberfn() { }
}

function fn() {}


print("A.memberfn="+A.memberfn+"    fn="+fn);
A.memberfn <- fn;
print("A.memberfn="+A.memberfn+"    fn="+fn);
A.memberfn <- fn;
print("A.memberfn="+A.memberfn+"    fn="+fn);

print("D.memberfn="+D.memberfn+"    fn="+fn);
D.memberfn <- fn;
print("D.memberfn="+D.memberfn+"    fn="+fn);
D.memberfn <- fn;
print("D.memberfn="+D.memberfn+"    fn="+fn);


Output:
Code:
A.memberfn=(function : 0x064E1050)    fn=(function : 0x064DA0C0)
A.memberfn=(function : 0x064DA0C0)    fn=(function : 0x064DA0C0)
A.memberfn=(function : 0x064DA0C0)    fn=(function : 0x064DA0C0)

D.memberfn=(function : 0x064E1588)    fn=(function : 0x064DA0C0)
D.memberfn=(function : 0x064D9FC0)    fn=(function : 0x064DA0C0)
D.memberfn=(function : 0x064DFA18)    fn=(function : 0x064DA0C0)


Thanks
fagiano
#2 Posted : Monday, August 06, 2012 8:05:39 AM(UTC)
Rank: Advanced Member

Groups: Registered, Administrators
Joined: 6/11/2005(UTC)
Posts: 825

Thanks: 0 times
Was thanked: 36 time(s) in 29 post(s)
the closure is cloned to store the base class, this is to implement the 'base' pseudo variable.

ciao
Alberto
nitramc
#3 Posted : Monday, August 06, 2012 10:37:14 AM(UTC)
Rank: Member

Groups: Registered
Joined: 3/1/2011(UTC)
Posts: 16
Location: Buenos Aires, Argentina

Thanks: 2 times
Was thanked: 0 time(s) in 0 post(s)
Got it, thanks!

I'll have to keep track of all the clones, I guess...
nitramc
#4 Posted : Thursday, August 09, 2012 11:24:02 PM(UTC)
Rank: Member

Groups: Registered
Joined: 3/1/2011(UTC)
Posts: 16
Location: Buenos Aires, Argentina

Thanks: 2 times
Was thanked: 0 time(s) in 0 post(s)
Alberto, is there a way to know the originating function?

I'm guessing the clone just changes free variables/environment but keeps track of a single compiled function.

Even if it's not exported as an API call, could you point me in the right direction so I can hack it?
I'm keeping a map of all equal functions, but this map grows larger and slower with each function reload (I reload a lot of functions)

Thanks
fagiano
#5 Posted : Friday, August 10, 2012 5:21:09 AM(UTC)
Rank: Advanced Member

Groups: Registered, Administrators
Joined: 6/11/2005(UTC)
Posts: 825

Thanks: 0 times
Was thanked: 36 time(s) in 29 post(s)
maybe I should add a built-in function to compare 2 closures closure.identity() or something like that.
For now you could implement something like that by your own, sq_getfunctioninfo gives you structure that contains a "funcid". funcid is unique across all closures of the same function.

ciao
Alberto
nitramc
#6 Posted : Monday, August 20, 2012 1:49:27 PM(UTC)
Rank: Member

Groups: Registered
Joined: 3/1/2011(UTC)
Posts: 16
Location: Buenos Aires, Argentina

Thanks: 2 times
Was thanked: 0 time(s) in 0 post(s)
Thanks for the heads up! I've solved it.
I'll post the code I'm using in case someone else needs it.

NOTES:
* The path to the source code must be added as an additional include path (not the common squirrel path, the one with the .cpp files)
* I made it for Sqrat, but it can be worked out for vanilla squirrel or another binder


Code:
#include <squirrel.h>
#include <sqpcheader.h>
#include <sqvm.h>
#include <sqfuncproto.h>
#include <sqclosure.h>
#include <sqstring.h>
#include <sqclosure.h>
bool s_functionProtosAreEqual(Sqrat::Function fa, Sqrat::Function fb) {
    HSQOBJECT &a = fa.GetFunc(), &b = fb.GetFunc();
    if(!sq_isclosure(a) || !sq_isclosure(b)) return false;
    SQFunctionProto *pa = a._unVal.pClosure->_function;
    SQFunctionProto *pb = b._unVal.pClosure->_function;
    return pa == pb;
}


Code:
Sqrat::RootTable().Func("functionProtosAreEqual", &s_functionProtosAreEqual);
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Clean Slate theme by Jaben Cargman (Tiny Gecko)
Powered by YAF 1.9.4 | YAF © 2003-2010, Yet Another Forum.NET
This page was generated in 0.078 seconds.