Created
January 22, 2015 10:57
-
-
Save gmbeard/68d8065a3ff2c15d8296 to your computer and use it in GitHub Desktop.
Testing prototype inheritance in Chrome v8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
var c = new A_Child(); | |
c.methodA(); | |
c.methodB(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <v8.h> | |
#include <cassert> | |
#include <memory> | |
#include <functional> | |
#include <fstream> | |
#include <stdexcept> | |
#include <vector> | |
using IsolatePtr = std::unique_ptr<v8::Isolate, decltype(std::bind(&v8::Isolate::Dispose, std::placeholders::_1))>; | |
IsolatePtr | |
make_isolate() | |
{ | |
return { | |
v8::Isolate::New(), | |
std::bind(&v8::Isolate::Dispose, std::placeholders::_1) | |
}; | |
} | |
void | |
MethodACallback(v8::FunctionCallbackInfo<v8::Value> const& info) | |
{ | |
std::cout << "methodA called" << std::endl; | |
} | |
void | |
MethodBCallback(v8::FunctionCallbackInfo<v8::Value> const& info) | |
{ | |
std::cout << "methodB called" << std::endl; | |
} | |
v8::Handle<v8::FunctionTemplate> | |
create_parent(v8::Isolate* isolate) | |
{ | |
v8::EscapableHandleScope handle_scope{isolate}; | |
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); | |
t->SetClassName(v8::String::NewFromUtf8(isolate, "A_Parent")); | |
auto proto = t->PrototypeTemplate(); | |
proto->Set(v8::String::NewFromUtf8(isolate, "methodA"), v8::FunctionTemplate::New(isolate, MethodACallback)); | |
return handle_scope.Escape(t); | |
} | |
v8::Handle<v8::FunctionTemplate> | |
create_child(v8::Isolate* isolate, v8::Handle<v8::FunctionTemplate> parent) | |
{ | |
v8::EscapableHandleScope handle_scope{isolate}; | |
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); | |
t->SetClassName(v8::String::NewFromUtf8(isolate, "A_Child")); | |
t->Inherit(parent); | |
auto proto = parent->PrototypeTemplate(); | |
proto->Set(v8::String::NewFromUtf8(isolate, "methodB"), v8::FunctionTemplate::New(isolate, MethodBCallback)); | |
return handle_scope.Escape(t); | |
} | |
v8::Handle<v8::Script> | |
compile_script(v8::Isolate* isolate, std::string const& file) | |
{ | |
v8::EscapableHandleScope handle_scope(isolate); | |
v8::Local<v8::Script> s{}; | |
std::ifstream f{file}; | |
if(!f) { | |
throw std::runtime_error{"Couldn't open file"}; | |
} | |
f.seekg(0, std::ios::end); | |
auto l = f.tellg(); | |
f.seekg(0, std::ios::beg); | |
std::vector<char> buf(l); | |
if(!f.read(&buf[0], l)) { | |
throw std::runtime_error{"Couldn't read contents of file"}; | |
} | |
f.close(); | |
auto source = v8::String::NewFromUtf8(isolate, &buf[0], v8::String::kNormalString, static_cast<int>(l)); | |
s = v8::Script::Compile(source); | |
return handle_scope.Escape(s); | |
} | |
int | |
main(int argc, char* argv[]) | |
{ | |
using namespace v8; | |
using namespace std; | |
using namespace std::placeholders; | |
V8::Initialize(); | |
auto vm = make_isolate(); | |
Isolate::Scope vm_scope{vm.get()}; | |
HandleScope scope{vm.get()}; | |
Handle<Context> ctx = Context::New(vm.get()); | |
v8::Context::Scope ctx_scope{ctx}; | |
auto parent = create_parent(vm.get()); | |
auto child = create_child(vm.get(), parent); | |
ctx->Global()->Set(v8::String::NewFromUtf8(vm.get(), "A_Child"), child->GetFunction()); | |
v8::Handle<v8::Script> script{}; | |
try { | |
script = compile_script(vm.get(), argv[1]); | |
} | |
catch(std::runtime_error& e) { | |
std::cout << "Error: " << e.what() << std::endl; | |
return 1; | |
} | |
script->Run(); | |
return 0; | |
} | |
t->Inherit(parent);//Inherit Useless
auto proto = parent->PrototypeTemplate();// what?this is =?
fuck
hey, guy. Can you tell me why need to use setClassName
? what work does it do in your program?
@chenxingshuang, if I recall, class constructors are just functions. Using setClassName
allows the function to be used as a class constructor through the use of new
. So, in this case, var c = new A_Child()
But even if I do not use setClassName
, it performs well with the use of new. And the program can not run now .
I just checked some documentation and it appears I’m mistaken; it’s only purpose seems to be to allow printing of class names. I’m in no way an expert on the V8 API. You should use whatever works for you.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How do Inherit c++ class;
such as :
Class A
{
void Acout()
{
std::cout<<"A"<<std::endl;
}
};
Class B : public A
{
void Bcout()
{
std::cout<<"B"<<std::endl;
}
};
JS test:
var b = new B();
b.Acout();