Hi, all!

After having bound hundreds of C-like functions i'm ready to bind my
first class in v8. i've got it working so far except that my Weak
Pointer callback isn't being triggered, and i have been unable to
figure out why. i'm pasting the code here - it's a bit long, but i
would really appreciate any insights on this, as i can't do ANY class-
level wrapping until i figure out how to get the objects deleted
properly.

Most of the code below was based on suggestions from:
  http://create.tpsitulsa.com/blog/2009/01/31/persistent-handles/
  http://create.tpsitulsa.com/blog/2009/01/29/v8-objects/

It's worth noting that the v8 sample code doesn't have any examples of
weak pointers :(.

The class i'm wrapping, PathFinder, can be considered opaque for our
purposes - the binding to the object appears to work, it's just that
my dtor (pf_dtor()) is never called.

The functions listed below are:

     - SetupPathFinderClass() sets up the class for JS-side access.
Installs the ctor and class instance prototype
     - pf_ctor() - the instance constructor
     - pf_dtor() - the weak pointer callback
     - pf_wrap() - associates a PathFinder JS object with a C++ object
and does the Persistent/Weak voodoo.

i've tried with and without HandleScopes, but the results are the same
- pf_dtor() is never being called.

The C++ code (JS code follows):


#include <v8/PathFinder.h>
#include <v8.h>
#include <v8/v8-convert.h>
#include <v8/v8-plugin.h>

#include <iostream> /* only for debuggering */
#ifndef CERR
#define CERR std::cerr << __FILE__ << ":" << std::dec << __LINE__ <<
" : "
#endif

namespace v8 { namespace p3 {
    using namespace ::v8::bind;
    using namespace ::v8::convert;

    //static const void * pf_bind_cx() { static const int x=7;return
&x;}

    static void pf_dtor(Persistent< Value > object, void *parameter)
    {
        CERR << "pf_dtor() PathFinder @"<<parameter<<'\n';
        PathFinder * pf = static_cast<PathFinder*>( parameter );
        //UnbindNative( pf_bind_cx(), parameter, pf );
        if( pf != &::v8::p3::plugin::PluginPath() )
        {
            delete pf;
        }
        object.Dispose();
        object.Clear();
    }

    static Persistent<Object> pf_wrap( Handle<Object> _self,
PathFinder * value )
    {
        //HandleScope scope;
        //BindNative( pf_bind_cx(), value, value );
        Persistent<Object> self( Persistent<Object>::New(_self) );
        self.MakeWeak( value, pf_dtor );
        self->SetInternalField(0,External::New(value));
        self->Set(String::New("bogo"),String::New("bogo was here"));
        CERR << "Wrapped PathFinder @"<<value<<" in a Persistent<Object>.\n";
        //return scope.Close(self);
        return self;
    }
    static Handle<Value> pf_ctor(const Arguments& argv)
    {
        if (!argv.IsConstructCall())
            return ThrowException(String::New("Cannot call constructor as
function"));

        const int argc = argv.Length();
        if( (1 == argc) && argv[0]->IsExternal() )
        {
            External * ex = External::Cast( *argv[0] );
            if( ex )
            {
                return pf_wrap( argv.This(), static_cast<PathFinder*>(ex->Value
()) );
            }
            else
            {
                return ThrowException(String::New("First argument to ctor failed
External::Cast()"));
            }
        }
        //HandleScope hscope;
        std::string a0 = (argc>0) ? JSToStdString(argv[0]) : "";
        std::string a1 = (argc>1) ? JSToStdString(argv[1]) : "";
        std::string a2 = (argc>2) ? JSToStdString(argv[2]) : "";
        CERR << "PathFinder(["<<a0<<"], ["<<a1<<"], ["<<a2<<"])\n";
        PathFinder * pf = new PathFinder( a0, a1, a2 );
        //return hscope.Close( pf_wrap( argv.This(), pf ) );
        return pf_wrap( argv.This(), pf );
        //return hscope.Close( pf_wrap( argv.This(), pf ) );
    }

    Handle<Value> SetupPathFinderClass(const Handle<Object> target )
    {
        // Set up prototype:
        Handle<FunctionTemplate> ctor = FunctionTemplate::New(pf_ctor);
        Local<ObjectTemplate> objt = ctor->InstanceTemplate();
        objt->SetInternalFieldCount(1);

        // Install ctor:
        Handle<Function> pffunc( ctor->GetFunction() );
        target->Set(String::New("PathFinder"), pffunc );

        // Install instance wrapping PluginPath() shared object:
        Handle<Value> pfex( External::New( &::v8::p3::plugin::PluginPath
() ) );
        Handle<Object> pfobj = pffunc->NewInstance( 1, &pfex );
        pffunc->Set(String::New("plugins"), pfobj );
        return pfobj;
    }

}} // namespaces


i've created hundreds of PathFinder objects in small scopes to try to
force GC, but my debugging message in pf_dtor() never gets output:

var my = {p:null};
{
    for( var i  = 0; i < 5; ++i )
    {
        var p = ['/usr/bin','/bin','~/bin'];
        my.p = new PathFinder(p.join(''+i),"",""+i);
        //delete my.p;
    }
    print('my.p=',my.p,typeof my.p,my.p.bogo);
    delete my.p;
    print('my.p=',my.p);
}
print('my.p=',my.p);
print
('PathFinder.plugins=',PathFinder.plugins,PathFinder.plugins.bogo);
print("Bye!");


The output is:

step...@jareth:~/cvs/fossil/v8-addons/addons$ m && ./shell js/pf.js
make: Nothing to be done for `default'.
PathFinder-js.cc:43 : Wrapped PathFinder @0xb7c940a0 in a
Persistent<Object>.
PathFinder-js.cc:69 : PathFinder([/usr/bin0/bin0~/bin], [], [0])
PathFinder-js.cc:43 : Wrapped PathFinder @0x88cda78 in a
Persistent<Object>.
PathFinder-js.cc:69 : PathFinder([/usr/bin1/bin1~/bin], [], [1])
PathFinder-js.cc:43 : Wrapped PathFinder @0x88cda40 in a
Persistent<Object>.
PathFinder-js.cc:69 : PathFinder([/usr/bin2/bin2~/bin], [], [2])
PathFinder-js.cc:43 : Wrapped PathFinder @0x88cdc10 in a
Persistent<Object>.
PathFinder-js.cc:69 : PathFinder([/usr/bin3/bin3~/bin], [], [3])
PathFinder-js.cc:43 : Wrapped PathFinder @0x88cdd00 in a
Persistent<Object>.
PathFinder-js.cc:69 : PathFinder([/usr/bin4/bin4~/bin], [], [4])
PathFinder-js.cc:43 : Wrapped PathFinder @0x88cddf0 in a
Persistent<Object>.
my.p= [object Object] object bogo was here
my.p= undefined
my.p= undefined
PathFinder.plugins= [object Object] bogo was here
Bye!
---------------------------------------
(end demo)


:-?

--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---

Reply via email to