Bugs in by_pointer_binding.py

6 views
Skip to first unread message

Aaron

unread,
Aug 26, 2009, 3:08:10 AM8/26/09
to nixysa-users
I'm still getting used to nixysa but in addition to the bug I found
yesterday where null objects were not being returned properly when
using the by_pointer binding model (posted this as an issue on
code.google.com), I found shortly after another error related to a
named variable substitution that doesn't exist. Patch for both
changes:

--- a/plugin/third_party/nixysa/by_pointer_binding.py
+++ b/plugin/third_party/nixysa/by_pointer_binding.py
@@ -334,6 +341,7 @@ static void Deallocate(NPObject *header) {
}

NPAPIObject *GetNPObject(NPP npp, ${Class} *object) {
+ if(object == NULL) return NULL;
NPAPIObject *npobject = static_cast<NPAPIObject *>(
NPN_CreateObject(npp, &npclass));
npobject->set_value(object);
@@ -398,11 +406,11 @@ if (NPVARIANT_IS_OBJECT(${input})) {
if (npobject->_class == ${ClassGlueNS}::GetNPClass()) {
${variable} = static_cast<${ClassGlueNS}::NPAPIObject *>
(npobject);
} else {
- *error_handle = "Error in " ${context}
+ *error_handle = "Error in " NPAPI_GLUE_EXCEPTION_CONTEXT
": type mismatch.";
}
} else {
- *error_handle = "Error in " ${context}
+ *error_handle = "Error in " NPAPI_GLUE_EXCEPTION_CONTEXT
": was expecting an object.";
}
${success} = ${variable} != NULL;

Another issue I ran into was garbage collection. I wanted to use a
factory design pattern in my app.
Think "var cam = flash.media.Camera.getCamera(0);" only in JavaScript.

While [binding_model=by_pointer] avoids copy constructors and
assignment operators, theres no notification when an object gets
destroyed.
I ended up modifying by_pointer_binding.py to do this and inherited my
classes from a reference counting base class. This is clearly not
ideal as it will break any implementations that don't implement the
reference counting functions I have defined but for me it does exactly
what I wanted it to.

What I'm wondering is if anyone here has thought about this and has
any other ideas? I'd be happy to change the code if need be.

Patch for reference counting [binding_model=by_pointer] classes:

--- a/plugin/third_party/nixysa/by_pointer_binding.py
+++ b/plugin/third_party/nixysa/by_pointer_binding.py
@@ -298,10 +298,17 @@ class NPAPIObject : public NPObject {
${Class} *value_;
public:
NPAPIObject(NPP npp): npp_(npp), value_() { }
+ ~NPAPIObject() { set_value(NULL); }
NPP npp() { return npp_; }
${Class} *value() { return value_; }
${Class} *value_mutable() { return value_; }
- void set_value(${Class} *value) { value_ = value; }
+ void set_value(${Class} *value) {
+ if(value_) {
+ if(value) value->duplicate();
+ value_->release();
+ }
+ value_ = value;
+ }
};


Antoine Labour

unread,
Aug 27, 2009, 11:01:10 PM8/27/09
to nixysa...@googlegroups.com
On Wed, Aug 26, 2009 at 12:08 AM, Aaron <aaro...@gmail.com> wrote:

I'm still getting used to nixysa but in addition to the bug I found
yesterday where null objects were not being returned properly when
using the by_pointer binding model (posted this as an issue on
code.google.com), I found shortly after another error related to a
named variable substitution that doesn't exist. Patch for both
changes:

Hi Aaron,

Thanks for trying nixysa, and sorry about the poor state of documentation.

Your first patch looks very sensible, and I will apply it shortly.
 

Another issue I ran into was garbage collection. I wanted to use a
factory design pattern in my app.
Think "var cam = flash.media.Camera.getCamera(0);" only in JavaScript.

While [binding_model=by_pointer] avoids copy constructors and
assignment operators, theres no notification when an object gets
destroyed.
I ended up modifying by_pointer_binding.py to do this and inherited my
classes from a reference counting base class. This is clearly not
ideal as it will break any implementations that don't implement the
reference counting functions I have defined but for me it does exactly
what I wanted it to.

What I'm wondering is if anyone here has thought about this and has
any other ideas? I'd be happy to change the code if need be.

Patch for reference counting [binding_model=by_pointer] classes:
 
As you noticed, the by_pointer binding model doesn't handle lifetime of temporary objects. It is assumed that the by_pointer objects are alive as long as the plugin is.
However nixysa is meant to be extended to support more binding models, that is, to support different types of C++ object models. In essence that is what you are doing with your patch. To remove the need to patch nixysa to build your plugins, you can create your own binding model, following what by_pointer_binding.py does (or directly forwarding calls to the various functions to the by_pointer_binding.py ones, if that suits your needs), and call the code generator with an extra argument, '--binding-module=my_type:path/to/my_type_binding.py', and then tag your classes with [binding_model=my_type] instead of by_pointer. You can add as many binding models as you wish.
o3d does that as well, it defines its own binding model derived from by_pointer, and tags most of its objects with it, and deals with object lifetime using ref-counting. See http://src.chromium.org/svn/trunk/src/o3d/plugin/o3d_binding.py and the build rules in http://src.chromium.org/svn/trunk/src/o3d/plugin/build.scons (and the various idl files in http://src.chromium.org/svn/trunk/src/o3d/plugin/idl ). 

I hope that helps,
Antoine
Reply all
Reply to author
Forward
0 new messages