Skip to content

Instantly share code, notes, and snippets.

@gmbeard
Created January 22, 2015 10:57
Show Gist options
  • Save gmbeard/68d8065a3ff2c15d8296 to your computer and use it in GitHub Desktop.
Save gmbeard/68d8065a3ff2c15d8296 to your computer and use it in GitHub Desktop.
Testing prototype inheritance in Chrome v8
"use strict";
var c = new A_Child();
c.methodA();
c.methodB();
#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;
}
@chenxingshuang
Copy link

hey, guy. Can you tell me why need to use setClassName? what work does it do in your program?

@gmbeard
Copy link
Author

gmbeard commented Sep 10, 2019

@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()

@chenxingshuang
Copy link

But even if I do not use setClassName , it performs well with the use of new. And the program can not run now .

@gmbeard
Copy link
Author

gmbeard commented Sep 10, 2019

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