Added a comment to the gist with one possible work-around for the inheritance 
issue:

https://gist.github.com/982157#gistcomment-31654

There must be a better way to deal with this though... Suggestions welcome.

L.

On 2011-05-19, at 9:34 PM, Laurie Harper wrote:

> I put all the code into a gist which can be downloaded, built and tested 
> locally:
> 
> $ git clone git://gist.github.com/982157.git
> $ cd 982157
> $ node-waf configure build 
> $ node VectorTests.js 
> Vector is function Vector() { [native code] }
> Vector.proto is [object Object]
> v is { x: 1 }
> v.x is  1
> v is { x: 9 }
> v.x is  9
> Assertion failed: (handle->InternalFieldCount() > 0), function Wrap, file 
> /Users/laurie/.nvm/v0.4.5/include/node/node_object_wrap.h, line 61.
> Abort trap
> 
> L.
> 
> On 2011-05-19, at 8:22 PM, Laurie Harper wrote:
> 
>> Oops, there's a line missing from the JavaScript inheritance setup code; it 
>> should read:
>> 
>> function f() {};  f.prototype = Vector.prototype;
>> function g() { Vector.apply(this, arguments) } 
>> g.prototype = new f();
>> var v = new g(1,2,3); 
>> 
>> It's correct in my test suite, so my questions still stand...
>> 
>> On 2011-05-19, at 4:31 PM, Laurie Harper wrote:
>> 
>>> Hi, I posted these issues first to the Node mailing list as the errors I'm 
>>> seeing are coming from assertions in Node's API, but they appear to be a 
>>> direct result of how the v8 JavaScript <-> C++ bridge works, so I'm 
>>> bringing them here for further clarification. I'll include the full 
>>> stripped-down C++ code I'm testing with below.
>>> 
>>> So far I have two problems, both of which I think stem from the same 
>>> underlying issue. The first is that if I set up accessors on the prototype 
>>> of my c++ proxy I'm unable to unwrap the internal field object; switching 
>>> from t->PrototypeTemplate()->SetAccessor() to 
>>> t->InstanceTemplate()->SetAccessor() resolved the problem (see commented 
>>> line in Initialize() in the code below. Strangely, setting a method on the 
>>> prototype seems to work just fine. So, question: why does it not work to 
>>> set an accessor on the prototype?
>>> 
>>> The second problem comes when I try to set up inheritance in JavaScript 
>>> from an object defined in c++. I think I understand why this one fails, but 
>>> have no idea how to fix it... I'm using test code like this, where Vector 
>>> is defined in c++ as show below:
>>> 
>>> function f() {};  f.prototype = Vector.prototype;
>>> function g() { Vector.apply(this, arguments) }
>>> var v = new g(1,2,3);
>>> 
>>> That emulates a common pattern for inheritance in JavaScript to avoid 
>>> calling the base type constructor when setting up the prototype of the 
>>> inheriting class. I think the problem is that, since there is no explicit 
>>> 'new Vector' anywhere, the c++ instantiation logic isn't fired at the right 
>>> time. The result is that Arguments::This() returns an object of an 
>>> unexpected type (?) and wrapping/unwrapping the proxied object fails. So, 
>>> the question is how to adjust my code to work when a constructor is called 
>>> without the 'new' operator I think?
>>> 
>>> Here's the test code I'm working with:
>>> 
>>> *** Vector.h:
>>> 
>>> class Vector: public node::ObjectWrap {
>>> public:
>>>  static Persistent<FunctionTemplate> ctor;
>>>  static void Initialize(Handle<Object> target);
>>> 
>>>  static Handle<Value> GetX(Local<String> property, const AccessorInfo& 
>>> info);
>>>  static void SetX(Local<String> property, Local<Value> value, const 
>>> AccessorInfo& info);
>>> 
>>> protected:
>>>  static Handle<Value> New(const Arguments &args);
>>>  Vector(btScalar &x, btScalar &y, btScalar &z);
>>> 
>>> private:
>>>  btVector3* m_btVector3;
>>> };
>>> 
>>> *** Vector.cc:
>>> 
>>> Persistent<FunctionTemplate> Vector::ctor;
>>> 
>>> void
>>> Vector::Initialize(Handle<Object> target) {
>>> HandleScope scope;
>>> 
>>> ctor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
>>> ctor->InstanceTemplate()->SetInternalFieldCount(1);
>>> ctor->SetClassName(String::NewSymbol("Vector"));
>>> 
>>> // ctor->PrototypeTemplate()->SetAccessor(String::NewSymbol("x"), GetX, 
>>> SetX);
>>> ctor->InstanceTemplate()->SetAccessor(String::NewSymbol("x"), GetX, SetX);
>>> 
>>> target->Set(String::NewSymbol("Vector"), ctor->GetFunction());
>>> }
>>> 
>>> Handle<Value>
>>> Vector::New(const Arguments &args) {
>>> float x, y, z;
>>> HandleScope scope;
>>> 
>>> if (args.Length() == 1 && args[0]->IsArray()) {
>>> x = args[0]->ToObject()->Get(0)->NumberValue();
>>> y = args[0]->ToObject()->Get(1)->NumberValue();
>>> z = args[0]->ToObject()->Get(2)->NumberValue();
>>> } else {
>>> x = args[0]->IsNumber() ? args[0]->NumberValue() : 0;
>>> y = args[1]->IsNumber() ? args[1]->NumberValue() : 0;
>>> z = args[2]->IsNumber() ? args[2]->NumberValue() : 0;
>>> }
>>> 
>>> Vector* obj = new Vector(x, y, z);
>>> obj->Wrap(args.This());
>>> return args.This();
>>> }
>>> 
>>> Vector::Vector(btScalar &x, btScalar &y, btScalar &z) {
>>> m_btVector3 = new btVector3(x, y, z);
>>> }
>>> 
>>> Handle<Value> 
>>> Vector::GetX(Local<String> property, const AccessorInfo& info) {
>>> HandleScope scope;
>>> // Vector* v = ObjectWrap::Unwrap<Vector>(info.This()); // This vs. Holder?
>>> Vector* v = ObjectWrap::Unwrap<Vector>(info.Holder()); // This vs. Holder?
>>> Local<Number> result = Number::New(v->m_btVector3->getX());
>>> return scope.Close(result);
>>> }
>>> 
>>> void
>>> Vector::SetX(Local<String> property, Local<Value> value, const 
>>> AccessorInfo& info) {
>>> Vector* v = ObjectWrap::Unwrap<Vector>(info.Holder());
>>> v->m_btVector3->setX(value->NumberValue());
>>> }
>>> 
>>> -- 
>>> Laurie Harper
>>> http://laurie.holoweb.net/
>>> 
>>> -- 
>>> v8-users mailing list
>>> [email protected]
>>> http://groups.google.com/group/v8-users
>> 
>> -- 
>> Laurie Harper
>> http://laurie.holoweb.net/
>> 
>> -- 
>> v8-users mailing list
>> [email protected]
>> http://groups.google.com/group/v8-users
> 
> -- 
> Laurie Harper
> http://laurie.holoweb.net/
> 
> -- 
> v8-users mailing list
> [email protected]
> http://groups.google.com/group/v8-users

-- 
Laurie Harper
http://laurie.holoweb.net/

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

Reply via email to