[v8-users] Inheriting a C++ class in JavaScript

2018-02-02 Thread Cvetan Stefanovski
Hello,

I am using V8 to expose a C++ API to JavaScript, and I have a use-case where 
one would need to have a JavaScript class that inherit from a C++ class. I've 
seen from V8 test code how they test the inheritance  thing there, but I 
couldn't find anything that was specific to my case. I've exhausted all 
resources that I could find on Google on this issue so I figured someone might 
help here.

I've attached a simplified code snippet for my case. It contains the class that 
I expose and the way I use it in JavaScript, so maybe someone can spot what I 
am missing.

Thanks in advance.

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
#include "v8.h"

class CppClass {
public:
CppClass() {
v8::Isolate* isolate = v8::Isolate::GetCurrent();

mAnotherCppClass = new AnotherCppClass();
mJsAnotherCppClass.Reset(isolate, 
AnotherCppClass::Wrap(mAnotherCppClass));
}

float MyCppMethod() {
return 2.f + 2.f;
}

// V8 Stuff
static v8::Local Bind() {
v8::Isolate* isolate = v8::Isolate::GetCurrent();

auto funcTemplate = v8::FunctionTemplate::New(isolate, 
CppClass_Constructor);
funcTemplate->SetClassName(v8::String::NewFromUtf8(isolate, 
"CppClass"));
funcTemplate->InstanceTemplate()->SetInternalFieldCount(1);


funcTemplate->InstanceTemplate()->SetAccessor(v8::String::NewFromUtf8(isolate, 
"object"), GetObject);
funcTemplate->PrototypeTemplate()->Set(v8::String::NewFromUtf8(isolate, 
"myCppMethod", v8::NewStringType::kNormal).ToLocalChecked(),
v8::FunctionTemplate::New(isolate, MyCppMethod_Callback));

functionTemplate.Reset(isolate, funcTemplate);
return functionTemplate.Get(isolate);
}

static v8::Local Wrap(CppClass* obj) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::EscapableHandleScope handleScope(isolate);

v8::Local instance = 
functionTemplate->InstanceTemplate()->NewInstance();
instance->SetInternalField(0, obj);

return handleScope.Escape(instance);
}

static CppClass* Unwrap(v8::Local object) {
return (CppClass*)object->GetInternalField(0);
}

static void CppClass_Constructor(const v8::FunctionCallbackInfo& 
args) {
if (!args.IsConstructCall()) {
isolate->ThrowException(v8::String::NewFromUtf8(isolate, "CppClass 
cannot be call as function. Use 'new' to instantiate"));
return;
}

CppClass* newObject = new CppClass();
args.GetReturnValue().Set(CppClass::Wrap(newObject));
}

static void GetObject(v8::Local property, const 
v8::PropertyCallbackInfo& info) {
CppClass* obj = CppClass::Unwrap(info.Holder());

info.GetReturnValue().Set(obj->mJsAnotherCppClass.Get(v8::Isolate::GetCurrent()));
}

static void MyCppMethod_Callback(const v8::FunctionCallbackInfo& 
args) {
CppClass* obj = CppClass::Unwrap(args.This());
args.GetReturnValue().Set(obj->MyMethod());
}

static v8::Persistent functionTemplate;

private:
AnotherCppClass* mAnotherCppClass;
v8::Persistent mJsAnotherCppClass;
};


/// Somewhere in code...

globalObjectTemplate->Set(v8::String::NewFromUtf8(isolate, "CppClass", 
v8::NewStringType::kNormal).ToLocalChecked(), CppClass::Bind());


/* ** JavaScript code *** */

class DerivedJsClass extends CppClass {
constructor() {
super();
this.something = 1;
}

myJsMethod() {
return this.something + 2;
}
}

// With above code unmodified:
var obj = new DerivedJsClass(); // Exception: CppClass cannot be call as 
function. Use 'new' to instantiate

// When calling args.GetReturnValue().Set(args.This()) in CppClass_Constructor:
var obj = new DerivedJsClass();
console.log(obj.myCppMethod()); // prints 4
console.log(obj.myJsMethod());  // prints 3
console.log(obj.object);// prints undefined


[v8-users] Re: Inheriting a C++ class in JavaScript

2018-02-06 Thread Cvetan Stefanovski
I've tried that already and it's same result. I cannot get past that 
IsConstructCall check no matter what I do. So clearly I miss something when 
building the templates.

V8 documentation is vague, almost non-existent for complex cases like this, so 
not helpful at all...

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.