SungchulCho / v8-juice

Automatically exported from code.google.com/p/v8-juice
Other
0 stars 0 forks source link

Feature request: bind native member functions as proxies for JS member var access #12

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
We can bind member funcs and member vars, but we would like to be able to do:

binder.BindMemberAccessor<something(?),&Foo::getSomething,&Foo::setSomething>("b
ar");

such that JS-side access to foo.bar will go through the given accessor
functions (though the API would probably define one routine each for
get/set access).

This is conceptually the C++ equivalent of something like:

foo.__defineGetter__("bar", function(){return 3;} );
foo.__defineSetter__("bar", function(x){foo._x = x;} );

This has some significant data typing problems, though, and i'm not
immediately certain of how to solve them.

e.g.

struct Foo {
private:
   Bar _bar;
public:
  Bar getBar() const; // constness can also be problematic
  void setBar( Bar ); // see below
};

Notable questions:

1) what should getBar()/setBar() return/accept as a param type (Bar, Bar &,
Bar const &, Bar *, Bar const *)?

2) What should setBar() return? (In the general case void, but some setters
like to return the old value.)

Of course we could require that the get/set always pass by values of the
exact same type, but that limits the usefulness of this feature. e.g. it is
common to pass a (const &) to the setter but return by value from the
getter (see v8::juice::PathFinder for many examples). If the types are to
be different, we probably need some underlying template magic to
automatically convert (where possible) the Bar arguments, e.g. (Bar & -->
Bar) or (Bar * --> Bar), and some such conversions are dangerous (e.g. Bar
const & --> Bar const *, since (const &) often points to a temporary objects).

There are other subtle problems, e.g. what happens if someone defines a
getter, but not a setter, and then in JS the client assigns the member to
some completely bogus value (e.g. wrong data type)?

Hmmm...

Original issue reported on code.google.com by sgbeal@googlemail.com on 11 Oct 2009 at 7:28

GoogleCodeExporter commented 8 years ago

Original comment by sgbeal@googlemail.com on 11 Oct 2009 at 7:28

GoogleCodeExporter commented 8 years ago
i'm a moron: i've been attacking this from the angle of binding native member 
funcs
to native member vars, which is not at all what we need/want here. We need to 
bind
native member functions to JS member properties. That sounds much more doable.

Original comment by sgbeal@googlemail.com on 13 Oct 2009 at 2:01

GoogleCodeExporter commented 8 years ago
Rough (proof of concept) impl is in r719.

i've run into the problem that the getter and setter MUST (because of 
limitations of
the v8 API) be defined at the same time. Calling this binding is REALLY ugly 
right
now, largely because the setter may return an arbitrary type (which is ignored 
for
this purpose) and may take a different argument type than the getter. So i'd 
like to
find a way to clean up the call, which currently looks like:

struct my_native
{
    std::string str;
private:
    int proxied;
public:
    int propGetter() const
    {
        CERR << "my_native::propGetter()\n";
        return this->proxied;
    }
    int propSetter(int v)
    {
        CERR << "my_native::propSetter("<<v<<")\n";
        return this->proxied = v;
    }
...
};

binder.BindPropToMemFuncs< int, &MY::propGetter, int, int, &MY::propSetter >(
"proxiedProp" );

TODOs:

- Overloads for various constnesses (constessi?).

- Overloads for setting either getter or setter without requiring the other 
(with the
caveat that calling both may overwrite the one which is called first with a null
accessor).

- Various typing-related overloads, to handle the case where the pass/return 
types
are all the same.

Original comment by sgbeal@googlemail.com on 15 Oct 2009 at 8:25

GoogleCodeExporter commented 8 years ago
r720 in the "edge" branch implements most of what we need here, i think. It's
possible to bind a getter/setter combination, or a getter-only, but not a 
setter-only
because v8 craps out if we do that (crashes because getter is 0).

There may be touch-ups to do here, but it's working for the basic cases.

Original comment by sgbeal@googlemail.com on 15 Oct 2009 at 10:24