Skip to content

Instantly share code, notes, and snippets.

@godfat
Last active March 10, 2017 04:46
Show Gist options
  • Save godfat/5107349 to your computer and use it in GitHub Desktop.
Save godfat/5107349 to your computer and use it in GitHub Desktop.
V8 weak reference example
// clang++ -Wall -Isrc -Iinclude weak.cpp -lv8
// https://developers.google.com/v8/get_started
// https://developers.google.com/v8/embed
// see also:
// https://groups.google.com/forum/?fromgroups=#!topic/v8-users/HedVREMsumU
#include <v8.h>
#include <iostream>
class ScopeVM{
public:
ScopeVM(): context_(v8::Context::New()), context_scope_(context_){}
private:
// Create a stack-allocated handle scope.
v8::HandleScope handle_scope_;
// Create a new context.
v8::Handle<v8::Context> context_;
// Enter the created context for compiling and
// running the hello world script.
v8::Context::Scope context_scope_;
};
struct Payload{
int i;
char c;
};
using namespace v8;
static void callback(Persistent<Value> handle, void* data){
Payload* payload = reinterpret_cast<Payload*>(data);
printf("Payload: %i, %c\n", payload->i, payload->c);
handle.Dispose();
}
static Handle<Value> hello(){
// You'll need this for every scope which needs to work with handles
HandleScope scope;
// Create a string containing the JavaScript source code.
Handle<String> source = String::New("'Hello, ' + 'World!'");
// Compile the source code.
Handle<Script> script = Script::Compile(source);
// Run the script to get the result.
Handle<Value> result(script->Run());
// Transfer the handle to outside world
return scope.Close(result);
}
static void work(Persistent<Value>& weak, Payload& payload){
HandleScope scope;
// Get the handle from other function
Handle<Value> result = hello();
// Make the weak reference to refer "Hello, World!"
weak = Persistent<Value>::New(result);
// And do really make it a weak reference and passing payload and callback
weak.MakeWeak(reinterpret_cast<void*>(&payload), &callback);
// Convert the result to an ASCII string and print it.
String::AsciiValue ascii(result);
printf("%s\n", *ascii);
}
static void gc_begin(GCType type, GCCallbackFlags flags){
std::cout << "GC begins: " << type << std::endl;
}
static void gc_end(GCType type, GCCallbackFlags flags){
std::cout << "GC ends: " << type << std::endl;
}
int main(int argc, char* argv[]){
ScopeVM vm; // Initialize the V8 VM
Payload payload = {1, 'a'}; // Payload we're passing to weak callback
Persistent<Value> weak; // We need weak reference stays alive
work(weak, payload);
v8::V8::AddGCPrologueCallback(&gc_begin);
v8::V8::AddGCEpilogueCallback(&gc_end);
// Here "Hello, World!" should be garbage collected, and call the callback
#ifdef HEAP
// http://v8.googlecode.com/svn/trunk/src/extensions/gc-extension.cc
HEAP -> CollectAllGarbage(v8::internal::Heap::kNoGCFlags);
#else
// force GC: http://www.my-ride-home.com/2011/01/v8-garbage-collection/
// Here "Hello, World!" should be garbage collected, and call the callback
while(!V8::IdleNotification()){};
#endif
return 0;
}
/*
Hello, World!
Payload: 1, a
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment