[gnode] Port to new node / V8



commit 605f523298124d41ecc119e73f9ce7d10b9588e8
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Nov 27 21:00:04 2015 -0800

    Port to new node / V8
    
    Not entirely working yet...

 src/function.cc |   66 +++++++++++++----------
 src/function.h  |    4 +-
 src/gi.cc       |   64 +++++++++++-----------
 src/gobject.cc  |  160 +++++++++++++++++++++++++++++--------------------------
 src/gobject.h   |    4 +-
 src/value.cc    |   70 ++++++++++++------------
 src/value.h     |    6 +-
 7 files changed, 194 insertions(+), 180 deletions(-)
---
diff --git a/src/function.cc b/src/function.cc
index def9854..c55f213 100644
--- a/src/function.cc
+++ b/src/function.cc
@@ -35,9 +35,9 @@ struct FunctionInfo {
     GIFunctionInvoker invoker;
 };
 
-static Handle<Value> FunctionInvoker(const Arguments &args) {
-    HandleScope scope;
-    FunctionInfo *func = (FunctionInfo *) External::Unwrap (args.Data ());
+static void FunctionInvoker(const FunctionCallbackInfo<Value> &args) {
+    Isolate *isolate = args.GetIsolate();
+    FunctionInfo *func = (FunctionInfo *) External::Cast (*args.Data ())->Value ();
 
     GIBaseInfo *info = func->info;
     GError *error = NULL;
@@ -57,8 +57,8 @@ static Handle<Value> FunctionInvoker(const Arguments &args) {
     }
 
     if (args.Length() < n_in_args) {
-        ThrowException (Exception::TypeError (String::New ("Not enough arguments.")));
-        return scope.Close (Undefined ());
+        isolate->ThrowException (Exception::TypeError (String::NewFromUtf8 (isolate, "Not enough 
arguments.")));
+        return;
     }
 
     gboolean is_method = ((g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0 &&
@@ -91,7 +91,7 @@ static Handle<Value> FunctionInvoker(const Arguments &args) {
             bool may_be_null = g_arg_info_may_be_null (&arg_info);
             GITypeInfo type_info;
             g_arg_info_load_type (&arg_info, &type_info);
-            V8ToGIArgument (&type_info, &callable_arg_values[i], args[i], may_be_null);
+            V8ToGIArgument (isolate, &type_info, &callable_arg_values[i], args[i], may_be_null);
         }
     }
 
@@ -117,48 +117,51 @@ static Handle<Value> FunctionInvoker(const Arguments &args) {
     }
 
     if (error) {
-        ThrowException (Exception::TypeError (String::New (error->message)));
-        return scope.Close (Undefined ());
+        isolate->ThrowException (Exception::TypeError (String::NewFromUtf8 (isolate, error->message)));
+        return;
     }
 
     GITypeInfo return_value_type;
     g_callable_info_load_return_type ((GICallableInfo *) info, &return_value_type);
-    return scope.Close (GIArgumentToV8 (&return_value_type, &return_value));
+    args.GetReturnValue ().Set (GIArgumentToV8 (isolate, &return_value_type, &return_value));
 }
 
-static void FunctionDestroyed(Persistent<Value> object, void *data) {
-    FunctionInfo *func = (FunctionInfo *) data;
+static void FunctionDestroyed(const WeakCallbackData<FunctionTemplate, FunctionInfo> &data) {
+    FunctionInfo *func = data.GetParameter ();
     g_base_info_unref (func->info);
-    g_function_invoker_destroy(&func->invoker);
+    g_function_invoker_destroy (&func->invoker);
     g_free (func);
 }
 
-Handle<Function> MakeFunction(GIBaseInfo *info) {
+Handle<Function> MakeFunction(Isolate *isolate, GIBaseInfo *info) {
     FunctionInfo *func = g_new0 (FunctionInfo, 1);
     func->info = g_base_info_ref (info);
 
     g_function_info_prep_invoker (func->info, &func->invoker, NULL);
 
-    Persistent<FunctionTemplate> tpl = Persistent<FunctionTemplate>::New (FunctionTemplate::New 
(FunctionInvoker, External::Wrap (func)));
-    tpl.MakeWeak (func, FunctionDestroyed);
+    Local<FunctionTemplate> tpl = FunctionTemplate::New (isolate, FunctionInvoker, External::New (isolate, 
func));
     Local<Function> fn = tpl->GetFunction ();
 
+    Persistent<FunctionTemplate> persistent(isolate, tpl);
+    persistent.SetWeak (func, FunctionDestroyed);
+
     const char *function_name = g_base_info_get_name (info);
-    fn->SetName (String::NewSymbol (function_name));
+    fn->SetName (String::NewFromUtf8 (isolate, function_name));
 
     return fn;
 }
 
+#if 0
 class TrampolineInfo {
     ffi_cif cif;
     ffi_closure *closure;
-    v8::Persistent<v8::Function> func;
+    Persistent<Function> persistent;
     GICallableInfo *info;
     GIScopeType scope_type;
 
-    TrampolineInfo(v8::Handle<v8::Function>  function,
-                   GICallableInfo           *info,
-                   GIScopeType               scope_type);
+    TrampolineInfo(Handle<Function>  function,
+                   GICallableInfo   *info,
+                   GIScopeType       scope_type);
 
     void Dispose();
     static void Call(ffi_cif *cif, void *result, void **args, void *data);
@@ -166,7 +169,7 @@ class TrampolineInfo {
 };
 
 void TrampolineInfo::Dispose() {
-    func.Dispose ();
+    persistent = nullptr;
     g_base_info_unref (info);
     g_callable_info_free_closure (info, closure);
 };
@@ -207,10 +210,11 @@ TrampolineInfo::TrampolineInfo(Handle<Function>  function,
     this->info = g_base_info_ref (info);
     this->scope_type = scope_type;
 }
+#endif
 
 struct Closure {
-    GClosure base_;
-    Persistent<Function> func;
+    GClosure base;
+    Persistent<Function> persistent;
 
     static void Marshal(GClosure *closure,
                         GValue   *g_return_value,
@@ -226,13 +230,17 @@ void Closure::Marshal(GClosure *base,
                       uint argc, const GValue *g_argv,
                       gpointer  invocation_hint,
                       gpointer  marshal_data) {
+    /* XXX: Any other way to get this? */
+    Isolate *isolate = Isolate::GetCurrent ();
+    HandleScope scope(isolate);
+
     Closure *closure = (Closure *) base;
-    Handle<Function> func = closure->func;
+    Handle<Function> func = Handle<Function>::New(isolate, closure->persistent);
 
     Handle<Value> argv[argc];
 
     for (uint i = 0; i < argc; i++)
-        argv[i] = GValueToV8 (&g_argv[i]);
+        argv[i] = GValueToV8 (isolate, &g_argv[i]);
 
     Handle<Object> this_obj = func;
     Handle<Value> return_value = func->Call (this_obj, argc, argv);
@@ -243,13 +251,13 @@ void Closure::Marshal(GClosure *base,
 
 void Closure::Invalidated(gpointer data, GClosure *base) {
     Closure *closure = (Closure *) base;
-    closure->func.Dispose();
+    closure->~Closure();
 }
 
-GClosure *MakeClosure(Handle<Function> function) {
+GClosure *MakeClosure(Isolate *isolate, Handle<Function> function) {
     Closure *closure = (Closure *) g_closure_new_simple (sizeof (*closure), NULL);
-    closure->func = Persistent<Function>::New (function);
-    GClosure *gclosure = &closure->base_;
+    closure->persistent.Reset(isolate, function);
+    GClosure *gclosure = &closure->base;
     g_closure_set_marshal (gclosure, Closure::Marshal);
     g_closure_add_invalidate_notifier (gclosure, NULL, Closure::Invalidated);
     return gclosure;
diff --git a/src/function.h b/src/function.h
index fc9bced..c3835a4 100644
--- a/src/function.h
+++ b/src/function.h
@@ -28,7 +28,7 @@
 
 namespace GNodeJS {
 
-v8::Handle<v8::Function> MakeFunction(GIBaseInfo *base_info);
-GClosure *MakeClosure(v8::Handle<v8::Function> function);
+v8::Handle<v8::Function> MakeFunction(v8::Isolate *isolate, GIBaseInfo *base_info);
+GClosure *MakeClosure(v8::Isolate *isolate, v8::Handle<v8::Function> function);
 
 };
diff --git a/src/gi.cc b/src/gi.cc
index 748cf40..db3014a 100644
--- a/src/gi.cc
+++ b/src/gi.cc
@@ -30,8 +30,8 @@
 
 using namespace v8;
 
-static void DefineEnumeration(Handle<Object> module_obj, GIBaseInfo *info) {
-    Handle<Object> enum_obj = Object::New ();
+static void DefineEnumeration(Isolate *isolate, Handle<Object> module_obj, GIBaseInfo *info) {
+    Handle<Object> enum_obj = Object::New (isolate);
 
     int n = g_enum_info_get_n_values(info);
     for (int i = 0; i < n; i++) {
@@ -41,64 +41,64 @@ static void DefineEnumeration(Handle<Object> module_obj, GIBaseInfo *info) {
         gint64 value_val = g_value_info_get_value (value_info);
 
         char *upcase_name = g_ascii_strup (value_name, -1);
-        enum_obj->Set (String::NewSymbol (upcase_name), Number::New (value_val));
+        enum_obj->Set (String::NewFromUtf8 (isolate, upcase_name), Number::New (isolate, value_val));
         g_free (upcase_name);
     }
 
     const char *enum_name = g_base_info_get_name (info);
-    module_obj->Set (String::NewSymbol (enum_name), enum_obj);
+    module_obj->Set (String::NewFromUtf8 (isolate, enum_name), enum_obj);
 }
 
-static void DefineConstant(Handle<Object> module_obj, GIBaseInfo *info) {
+static void DefineConstant(Isolate *isolate, Handle<Object> module_obj, GIBaseInfo *info) {
     GITypeInfo *type_info = g_constant_info_get_type ((GIConstantInfo *) info);
     GIArgument garg;
     g_constant_info_get_value ((GIConstantInfo *) info, &garg);
-    Handle<Value> value = GNodeJS::GIArgumentToV8 (type_info, &garg);
+    Handle<Value> value = GNodeJS::GIArgumentToV8 (isolate, type_info, &garg);
     g_base_info_unref ((GIBaseInfo *) type_info);
 
     const char *constant_name = g_base_info_get_name ((GIBaseInfo *) info);
-    module_obj->Set (String::NewSymbol (constant_name), value);
+    module_obj->Set (String::NewFromUtf8 (isolate, constant_name), value);
 }
 
-static void DefineFunction(Handle<Object> module_obj, GIBaseInfo *info) {
+static void DefineFunction(Isolate *isolate, Handle<Object> module_obj, GIBaseInfo *info) {
     const char *function_name = g_base_info_get_name ((GIBaseInfo *) info);
-    module_obj->Set (String::NewSymbol (function_name), GNodeJS::MakeFunction (info));
+    module_obj->Set (String::NewFromUtf8 (isolate, function_name), GNodeJS::MakeFunction (isolate, info));
 }
 
-static void DefineObject(Handle<Object> module_obj, GIBaseInfo *info) {
+static void DefineObject(Isolate *isolate, Handle<Object> module_obj, GIBaseInfo *info) {
     const char *class_name = g_base_info_get_name ((GIBaseInfo *) info);
-    module_obj->Set (String::NewSymbol (class_name), GNodeJS::MakeClass (info));
+    module_obj->Set (String::NewFromUtf8 (isolate, class_name), GNodeJS::MakeClass (isolate, info));
 }
 
-static void DefineInfo(Handle<Object> module_obj, GIBaseInfo *info) {
+static void DefineInfo(Isolate *isolate, Handle<Object> module_obj, GIBaseInfo *info) {
     GIInfoType type = g_base_info_get_type (info);
 
     switch (type) {
     case GI_INFO_TYPE_ENUM:
     case GI_INFO_TYPE_FLAGS:
-        DefineEnumeration (module_obj, info);
+        DefineEnumeration (isolate, module_obj, info);
         break;
     case GI_INFO_TYPE_CONSTANT:
-        DefineConstant (module_obj, info);
+        DefineConstant (isolate, module_obj, info);
         break;
     case GI_INFO_TYPE_FUNCTION:
-        DefineFunction (module_obj, info);
+        DefineFunction (isolate, module_obj, info);
         break;
     case GI_INFO_TYPE_OBJECT:
-        DefineObject (module_obj, info);
+        DefineObject (isolate, module_obj, info);
         break;
     default:
         break;
     }
 }
 
-static Handle<Value> ImportNS(const Arguments& args) {
+static void ImportNS(const FunctionCallbackInfo<Value> &args) {
+    Isolate *isolate = args.GetIsolate ();
     GIRepository *repo = g_irepository_get_default ();
-    HandleScope scope;
 
     if (args.Length() < 1) {
-        ThrowException (Exception::TypeError (String::New ("Wrong number of arguments")));
-        return scope.Close (Undefined ());
+        isolate->ThrowException (Exception::TypeError (String::NewFromUtf8 (isolate, "Wrong number of 
arguments")));
+        return;
     }
 
     String::Utf8Value ns_str (args[0]->ToString());
@@ -113,33 +113,31 @@ static Handle<Value> ImportNS(const Arguments& args) {
     GError *error = NULL;
     g_irepository_require (repo, ns, version, (GIRepositoryLoadFlags) 0, &error);
     if (error) {
-        ThrowException (Exception::TypeError (String::New (error->message)));
-        return scope.Close (Undefined ());
+        isolate->ThrowException (Exception::TypeError (String::NewFromUtf8 (isolate, error->message)));
+        return;
     }
 
-    Handle<Object> module_obj = Object::New ();
+    Handle<Object> module_obj = Object::New (isolate);
 
     int n = g_irepository_get_n_infos (repo, ns);
     for (int i = 0; i < n; i++) {
         GIBaseInfo *info = g_irepository_get_info (repo, ns, i);
-        DefineInfo (module_obj, info);
+        DefineInfo (isolate, module_obj, info);
         g_base_info_unref (info);
     }
 
-    return scope.Close (module_obj);
+    args.GetReturnValue ().Set (module_obj);
 }
 
-static Handle<Value> StartLoop(const Arguments& args) {
-    HandleScope scope;
-
+static void StartLoop(const FunctionCallbackInfo<Value> &args) {
     GNodeJS::StartLoop ();
-
-    return scope.Close (Undefined ());
 }
 
-void InitModule(Handle<Object> exports) {
-    exports->Set(String::NewSymbol("importNS"), FunctionTemplate::New(ImportNS)->GetFunction());
-    exports->Set(String::NewSymbol("startLoop"), FunctionTemplate::New(StartLoop)->GetFunction());
+void InitModule(Handle<Object> exports, Handle<Value> module, void *priv) {
+    Isolate *isolate = Isolate::GetCurrent ();
+
+    exports->Set (String::NewFromUtf8 (isolate, "importNS"), FunctionTemplate::New (isolate, 
ImportNS)->GetFunction ());
+    exports->Set (String::NewFromUtf8 (isolate, "startLoop"), FunctionTemplate::New (isolate, 
StartLoop)->GetFunction ());
 }
 
 NODE_MODULE(gi, InitModule)
diff --git a/src/gobject.cc b/src/gobject.cc
index b1aca4a..b4feb47 100644
--- a/src/gobject.cc
+++ b/src/gobject.cc
@@ -70,18 +70,18 @@ static void ToggleNotify(gpointer user_data, GObject *gobject, gboolean toggle_d
 
 G_DEFINE_QUARK(gnode_js_object, gnode_js_object);
 
-static void AssociateGObject(Handle<Object> object, GObject *gobject) {
-    object->SetPointerInInternalField (0, gobject);
+static void AssociateGObject(Isolate *isolate, Handle<Object> object, GObject *gobject) {
+    object->SetAlignedPointerInInternalField (0, gobject);
 
     g_object_ref_sink (gobject);
     g_object_add_toggle_ref (gobject, ToggleNotify, NULL);
 
-    Object *object_p = *object;
-    g_object_set_qdata (gobject, gnode_js_object_quark (), object_p);
+    Persistent<Object> *persistent = new Persistent<Object>(isolate, object);
+    g_object_set_qdata (gobject, gnode_js_object_quark (), persistent);
 }
 
-static Handle<Value> GObjectConstructor(const Arguments &args) {
-    HandleScope scope;
+static void GObjectConstructor(const FunctionCallbackInfo<Value> &args) {
+    Isolate *isolate = args.GetIsolate ();
 
     /* The flow of this function is a bit twisty.
 
@@ -91,8 +91,8 @@ static Handle<Value> GObjectConstructor(const Arguments &args) {
      * the constructor is called with one external. */
 
     if (!args.IsConstructCall ()) {
-        ThrowException (Exception::TypeError (String::New ("Not a construct call.")));
-        return scope.Close (Undefined ());
+        isolate->ThrowException (Exception::TypeError (String::NewFromUtf8 (isolate, "Not a construct 
call.")));
+        return;
     }
 
     Handle<Object> self = args.This ();
@@ -100,15 +100,15 @@ static Handle<Value> GObjectConstructor(const Arguments &args) {
     if (args[0]->IsExternal ()) {
         /* The External case. This is how WrapperFromGObject is called. */
 
-        void *data = External::Unwrap (args[0]);
+        void *data = External::Cast (*args[0])->Value ();
         GObject *gobject = G_OBJECT (data);
 
-        AssociateGObject (self, gobject);
+        AssociateGObject (isolate, self, gobject);
     } else {
         /* User code calling `new Gtk.Widget({ ... })` */
 
         GObject *gobject;
-        GIBaseInfo *info = (GIBaseInfo *) External::Unwrap(args.Data ());
+        GIBaseInfo *info = (GIBaseInfo *) External::Cast (*args.Data ())->Value ();
         GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info);
         void *klass = g_type_class_ref (gtype);
 
@@ -119,32 +119,23 @@ static Handle<Value> GObjectConstructor(const Arguments &args) {
             Local<Object> property_hash = args[0]->ToObject ();
 
             if (!InitGParametersFromProperty (&parameters, &n_parameters, klass, property_hash)) {
-                ThrowException (Exception::TypeError (String::New ("Unable to make GParameters.")));
+                isolate->ThrowException (Exception::TypeError (String::NewFromUtf8 (isolate, "Unable to make 
GParameters.")));
                 goto out;
             }
         }
 
         gobject = (GObject *) g_object_newv (gtype, n_parameters, parameters);
-        AssociateGObject (self, gobject);
+        AssociateGObject (isolate, self, gobject);
 
     out:
         g_free (parameters);
         g_type_class_unref (klass);
     }
-
-    return self;
 }
 
 G_DEFINE_QUARK(gnode_js_template, gnode_js_template);
 
-static void ClassDestroyed(Persistent<Value> object, void *data) {
-    GIBaseInfo *info = (GIBaseInfo *) data;
-    GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info);
-    g_type_set_qdata (gtype, gnode_js_template_quark (), NULL);
-    g_base_info_unref (info);
-}
-
-static void DefineConstructorMethods(Handle<FunctionTemplate> constructor, GIBaseInfo *info) {
+static void DefineConstructorMethods(Isolate *isolate, Handle<FunctionTemplate> constructor, GIBaseInfo 
*info) {
     int n_methods = g_object_info_get_n_methods (info);
     for (int i = 0; i < n_methods; i++) {
         GIFunctionInfo *meth_info = g_object_info_get_method (info, i);
@@ -152,15 +143,15 @@ static void DefineConstructorMethods(Handle<FunctionTemplate> constructor, GIBas
 
         if (!(flags & GI_FUNCTION_IS_METHOD)) {
             const char *function_name = g_base_info_get_name ((GIBaseInfo *) meth_info);
-            Handle<Function> fn = MakeFunction (meth_info);
-            constructor->Set (String::NewSymbol (function_name), fn);
+            Handle<Function> fn = MakeFunction (isolate, meth_info);
+            constructor->Set (String::NewFromUtf8 (isolate, function_name), fn);
         }
 
         g_base_info_unref ((GIBaseInfo *) meth_info);
     }
 }
 
-static void DefinePrototypeMethods(Handle<ObjectTemplate> prototype, GIBaseInfo *info) {
+static void DefinePrototypeMethods(Isolate *isolate, Handle<ObjectTemplate> prototype, GIBaseInfo *info) {
     int n_methods = g_object_info_get_n_methods (info);
     for (int i = 0; i < n_methods; i++) {
         GIFunctionInfo *meth_info = g_object_info_get_method (info, i);
@@ -168,91 +159,109 @@ static void DefinePrototypeMethods(Handle<ObjectTemplate> prototype, GIBaseInfo
 
         if (flags & GI_FUNCTION_IS_METHOD) {
             const char *function_name = g_base_info_get_name ((GIBaseInfo *) meth_info);
-            Handle<Function> fn = MakeFunction (meth_info);
-            prototype->Set (String::NewSymbol (function_name), fn);
+            Handle<Function> fn = MakeFunction (isolate, meth_info);
+            prototype->Set (String::NewFromUtf8 (isolate, function_name), fn);
         }
 
         g_base_info_unref ((GIBaseInfo *) meth_info);
     }
 }
 
-static Handle<Value> SignalConnectInternal(const Arguments &args, bool after) {
-    HandleScope scope;
-    GObject *gobject = GObjectFromWrapper(args.This ());
+static void SignalConnectInternal(const FunctionCallbackInfo<Value> &args, bool after) {
+    Isolate *isolate = args.GetIsolate ();
+    GObject *gobject = GObjectFromWrapper (args.This ());
 
     String::Utf8Value signal_name (args[0]->ToString ());
     Handle<Function> callback = Local<Function>::Cast (args[1]->ToObject ());
-    GClosure *gclosure = MakeClosure (callback);
+    GClosure *gclosure = MakeClosure (isolate, callback);
 
     ulong handler_id = g_signal_connect_closure (gobject, *signal_name, gclosure, after);
-    return scope.Close (Integer::NewFromUnsigned (handler_id));
+    args.GetReturnValue ().Set(Integer::NewFromUnsigned (isolate, handler_id));
 }
 
-static Handle<Value> SignalConnect(const Arguments &args) {
-    return SignalConnectInternal (args, false);
+static void SignalConnect(const FunctionCallbackInfo<Value> &args) {
+    SignalConnectInternal (args, false);
 }
 
-static Handle<FunctionTemplate> GetBaseClassTemplate() {
-    Local<FunctionTemplate> tpl = FunctionTemplate::New ();
+static Handle<FunctionTemplate> GetBaseClassTemplate(Isolate *isolate) {
+    Local<FunctionTemplate> tpl = FunctionTemplate::New (isolate);
     Handle<ObjectTemplate> proto = tpl->PrototypeTemplate ();
-    proto->Set (String::NewSymbol ("connect"), FunctionTemplate::New (SignalConnect)->GetFunction ());
-
+    proto->Set (String::NewFromUtf8 (isolate, "connect"), FunctionTemplate::New (isolate, 
SignalConnect)->GetFunction ());
     return tpl;
 }
 
-static Handle<FunctionTemplate> GetClassTemplateFromGI(GIBaseInfo *info);
+static Handle<FunctionTemplate> GetClassTemplateFromGI(Isolate *isolate, GIBaseInfo *info);
+
+static void ClassDestroyed(const WeakCallbackData<FunctionTemplate, GIBaseInfo> &data) {
+    GIBaseInfo *info = data.GetParameter ();
+    GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info);
+
+    void *type_data = g_type_get_qdata (gtype, gnode_js_template_quark ());
+    assert (type_data != NULL);
+    Persistent<FunctionTemplate> *persistent = (Persistent<FunctionTemplate> *) type_data;
+    delete persistent;
+
+    g_type_set_qdata (gtype, gnode_js_template_quark (), NULL);
+    g_base_info_unref (info);
+}
 
-static Handle<FunctionTemplate> GetClassTemplate(GIBaseInfo *info, GType gtype) {
+static Handle<FunctionTemplate> GetClassTemplate(Isolate *isolate, GIBaseInfo *info, GType gtype) {
     void *data = g_type_get_qdata (gtype, gnode_js_template_quark ());
+
     if (data) {
-        FunctionTemplate *tpl_p = (FunctionTemplate *) data;
-        Persistent<FunctionTemplate> tpl(tpl_p);
+        Persistent<FunctionTemplate> *persistent = (Persistent<FunctionTemplate> *) data;
+        Handle<FunctionTemplate> tpl = Handle<FunctionTemplate>::New (isolate, *persistent);
         return tpl;
     } else {
-        Persistent<FunctionTemplate> tpl = Persistent<FunctionTemplate>::New (FunctionTemplate::New 
(GObjectConstructor, External::Wrap (info)));
-        tpl.MakeWeak (g_base_info_ref (info), ClassDestroyed);
+        Handle<FunctionTemplate> tpl = FunctionTemplate::New (isolate, GObjectConstructor, External::New 
(isolate, info));
+
+        Persistent<FunctionTemplate> *persistent = new Persistent<FunctionTemplate>(isolate, tpl);
+        persistent->SetWeak (g_base_info_ref (info), ClassDestroyed);
+        g_type_set_qdata (gtype, gnode_js_template_quark (), persistent);
 
         const char *class_name = g_base_info_get_name (info);
-        tpl->SetClassName (String::NewSymbol (class_name));
+        tpl->SetClassName (String::NewFromUtf8 (isolate, class_name));
+
+        tpl->InstanceTemplate ()->SetInternalFieldCount (1);
 
-        FunctionTemplate *tpl_p = *tpl;
-        g_type_set_qdata (gtype, gnode_js_template_quark (), tpl_p);
+        DefineConstructorMethods (isolate, tpl, info);
+        DefinePrototypeMethods (isolate, tpl->PrototypeTemplate (), info);
 
         GIObjectInfo *parent_info = g_object_info_get_parent (info);
         if (parent_info) {
-            Handle<FunctionTemplate> parent_tpl = GetClassTemplateFromGI ((GIBaseInfo *) parent_info);
+            Handle<FunctionTemplate> parent_tpl = GetClassTemplateFromGI (isolate, (GIBaseInfo *) 
parent_info);
             tpl->Inherit (parent_tpl);
         } else {
-            tpl->Inherit (GetBaseClassTemplate ());
+            tpl->Inherit (GetBaseClassTemplate (isolate));
         }
 
-        tpl->InstanceTemplate ()->SetInternalFieldCount (1);
-
-        DefineConstructorMethods (tpl, info);
-        DefinePrototypeMethods (tpl->PrototypeTemplate (), info);
-
         return tpl;
     }
 }
 
-static Handle<FunctionTemplate> GetClassTemplateFromGI(GIBaseInfo *info) {
+static Handle<FunctionTemplate> GetClassTemplateFromGI(Isolate *isolate, GIBaseInfo *info) {
     GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info);
-    return GetClassTemplate (info, gtype);
+    return GetClassTemplate (isolate, info, gtype);
 }
 
-static Handle<FunctionTemplate> GetClassTemplateFromGType(GType gtype) {
+static Handle<FunctionTemplate> GetClassTemplateFromGType(Isolate *isolate, GType gtype) {
     GIRepository *repo = g_irepository_get_default ();
     GIBaseInfo *info = g_irepository_find_by_gtype (repo, gtype);
-    return GetClassTemplate (info, gtype);
+    return GetClassTemplate (isolate, info, gtype);
 }
 
-Handle<Function> MakeClass(GIBaseInfo *info) {
-    Handle<FunctionTemplate> tpl = GetClassTemplateFromGI (info);
+Handle<Function> MakeClass(Isolate *isolate, GIBaseInfo *info) {
+    Handle<FunctionTemplate> tpl = GetClassTemplateFromGI (isolate, info);
     return tpl->GetFunction ();
 }
 
-static void ObjectDestroyed(Persistent<Value> object, void *data) {
-    GObject *gobject = G_OBJECT (data);
+static void ObjectDestroyed(const WeakCallbackData<Object, GObject> &data) {
+    GObject *gobject = data.GetParameter ();
+
+    void *type_data = g_object_get_qdata (gobject, gnode_js_object_quark ());
+    assert (type_data != NULL);
+    Persistent<Object> *persistent = (Persistent<Object> *) type_data;
+    delete persistent;
 
     /* We're destroying the wrapper object, so make sure to clear out
      * the qdata that points back to us. */
@@ -264,45 +273,44 @@ static void ObjectDestroyed(Persistent<Value> object, void *data) {
 static void ToggleNotify(gpointer user_data, GObject *gobject, gboolean toggle_down) {
     void *data = g_object_get_qdata (gobject, gnode_js_object_quark ());
     assert (data != NULL);
-    Object *obj_p = (Object *) data;
-    Persistent<Object> obj(obj_p);
+
+    Persistent<Object> *persistent = (Persistent<Object> *) data;
 
     if (toggle_down) {
         /* We're dropping from 2 refs to 1 ref. We are the last holder. Make
          * sure that that our weak ref is installed. */
-        obj.MakeWeak (gobject, ObjectDestroyed);
+        persistent->SetWeak (gobject, ObjectDestroyed);
     } else {
         /* We're going from 1 ref to 2 refs. We can't let our wrapper be
          * collected, so make sure that our reference is persistent */
-        obj.ClearWeak ();
+        persistent->ClearWeak ();
     }
 }
 
-Handle<Value> WrapperFromGObject(GObject *gobject) {
+Handle<Value> WrapperFromGObject(Isolate *isolate, GObject *gobject) {
     void *data = g_object_get_qdata (gobject, gnode_js_object_quark ());
 
-    /* Easy case: we already have a wrapper. */
     if (data) {
-        Object *obj_p = (Object *) data;
-        Persistent<Object> obj(obj_p);
+        /* Easy case: we already have an object. */
+        Persistent<Object> *persistent = (Persistent<Object> *) data;
+        Handle<Object> obj = Handle<Object>::New (isolate, *persistent);
         return obj;
     } else {
         GType gtype = G_OBJECT_TYPE (gobject);
 
-        Handle<FunctionTemplate> tpl = GetClassTemplateFromGType (gtype);
+        Handle<FunctionTemplate> tpl = GetClassTemplateFromGType (isolate, gtype);
         Handle<Function> constructor = tpl->GetFunction ();
 
-        Handle<Value> gobject_external = External::New (gobject);
+        Handle<Value> gobject_external = External::New (isolate, gobject);
         Handle<Value> args[] = { gobject_external };
-        Local<Object> obj_local = constructor->NewInstance (1, args);
-        Persistent<Object> obj = Persistent<Object>::New (obj_local);
+        Handle<Object> obj = constructor->NewInstance (1, args);
         return obj;
     }
 }
 
 GObject * GObjectFromWrapper(Handle<Value> value) {
     Handle<Object> object = value->ToObject ();
-    void *data = object->GetPointerFromInternalField (0);
+    void *data = object->GetAlignedPointerFromInternalField (0);
     GObject *gobject = G_OBJECT (data);
     return gobject;
 }
diff --git a/src/gobject.h b/src/gobject.h
index 369d2d1..d87cb28 100644
--- a/src/gobject.h
+++ b/src/gobject.h
@@ -28,9 +28,9 @@
 
 namespace GNodeJS {
 
-v8::Handle<v8::Function> MakeClass(GIBaseInfo *info);
+v8::Handle<v8::Function> MakeClass(v8::Isolate *isolate, GIBaseInfo *info);
 
-v8::Handle<v8::Value> WrapperFromGObject(GObject *object);
+v8::Handle<v8::Value> WrapperFromGObject(v8::Isolate *isolate, GObject *object);
 GObject * GObjectFromWrapper(v8::Handle<v8::Value> value);
 
 };
diff --git a/src/value.cc b/src/value.cc
index ab98518..9829577 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -27,55 +27,55 @@ using namespace v8;
 
 namespace GNodeJS {
 
-Handle<Value> GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg) {
+Handle<Value> GIArgumentToV8(Isolate *isolate, GITypeInfo *type_info, GIArgument *arg) {
     GITypeTag type_tag = g_type_info_get_tag (type_info);
 
     switch (type_tag) {
     case GI_TYPE_TAG_VOID:
-        return Undefined ();
+        return Undefined (isolate);
 
     case GI_TYPE_TAG_BOOLEAN:
         if (arg->v_boolean)
-            return True ();
+            return True (isolate);
         else
-            return False ();
+            return False (isolate);
 
     case GI_TYPE_TAG_INT32:
-        return Integer::New (arg->v_int);
+        return Integer::New (isolate, arg->v_int);
     case GI_TYPE_TAG_UINT32:
-        return Integer::NewFromUnsigned (arg->v_uint);
+        return Integer::NewFromUnsigned (isolate, arg->v_uint);
     case GI_TYPE_TAG_INT16:
-        return Integer::New (arg->v_int16);
+        return Integer::New (isolate, arg->v_int16);
     case GI_TYPE_TAG_UINT16:
-        return Integer::NewFromUnsigned (arg->v_uint16);
+        return Integer::NewFromUnsigned (isolate, arg->v_uint16);
     case GI_TYPE_TAG_INT8:
-        return Integer::New (arg->v_int8);
+        return Integer::New (isolate, arg->v_int8);
     case GI_TYPE_TAG_UINT8:
-        return Integer::NewFromUnsigned (arg->v_uint8);
+        return Integer::NewFromUnsigned (isolate, arg->v_uint8);
     case GI_TYPE_TAG_FLOAT:
-        return Number::New (arg->v_float);
+        return Number::New (isolate, arg->v_float);
     case GI_TYPE_TAG_DOUBLE:
-        return Number::New (arg->v_double);
+        return Number::New (isolate, arg->v_double);
 
     /* For 64-bit integer types, use a float. When JS and V8 adopt
      * bigger sized integer types, start using those instead. */
     case GI_TYPE_TAG_INT64:
-        return Number::New (arg->v_int64);
+        return Number::New (isolate, arg->v_int64);
     case GI_TYPE_TAG_UINT64:
-        return Number::New (arg->v_uint64);
+        return Number::New (isolate, arg->v_uint64);
 
     case GI_TYPE_TAG_UNICHAR:
         {
-            char data[7];
-            int size = g_unichar_to_utf8 (arg->v_uint32, data);
-            return String::New (data, size);
+            char data[7] = { 0 };
+            g_unichar_to_utf8 (arg->v_uint32, data);
+            return String::NewFromUtf8 (isolate, data);
         }
 
     case GI_TYPE_TAG_UTF8:
         if (arg->v_pointer)
-            return String::New ((char *) arg->v_pointer);
+            return String::NewFromUtf8 (isolate, (char *) arg->v_pointer);
         else
-            return Null ();
+            return Null (isolate);
 
     case GI_TYPE_TAG_INTERFACE:
         {
@@ -84,7 +84,7 @@ Handle<Value> GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg) {
 
             switch (interface_type) {
             case GI_INFO_TYPE_OBJECT:
-                return WrapperFromGObject ((GObject *) arg->v_pointer);
+                return WrapperFromGObject (isolate, (GObject *) arg->v_pointer);
             default:
                 g_assert_not_reached ();
             }
@@ -96,9 +96,9 @@ Handle<Value> GIArgumentToV8(GITypeInfo *type_info, GIArgument *arg) {
     }
 }
 
-static GArray * V8ToGArray(GITypeInfo *type_info, Handle<Value> value) {
+static GArray * V8ToGArray(Isolate *isolate, GITypeInfo *type_info, Handle<Value> value) {
     if (!value->IsArray ()) {
-        ThrowException (Exception::TypeError (String::New ("Not an array.")));
+        isolate->ThrowException (Exception::TypeError (String::NewFromUtf8 (isolate, "Not an array.")));
         return NULL;
     }
 
@@ -111,7 +111,7 @@ static GArray * V8ToGArray(GITypeInfo *type_info, Handle<Value> value) {
         Local<Value> value = array->Get (i);
         GIArgument arg;
 
-        V8ToGIArgument (elem_info, &arg, value, false);
+        V8ToGIArgument (isolate, elem_info, &arg, value, false);
         g_array_append_val (garray, arg);
     }
 
@@ -119,14 +119,14 @@ static GArray * V8ToGArray(GITypeInfo *type_info, Handle<Value> value) {
     return garray;
 }
 
-void V8ToGIArgument(GITypeInfo *type_info, GIArgument *arg, Handle<Value> value, bool may_be_null) {
+void V8ToGIArgument(Isolate *isolate, GITypeInfo *type_info, GIArgument *arg, Handle<Value> value, bool 
may_be_null) {
     GITypeTag type_tag = g_type_info_get_tag (type_info);
 
     if (value->IsNull ()) {
         arg->v_pointer = NULL;
 
         if (!may_be_null)
-            ThrowException (Exception::TypeError (String::New ("Argument may not be null.")));
+            isolate->ThrowException (Exception::TypeError (String::NewFromUtf8 (isolate, "Argument may not 
be null.")));
 
         return;
     }
@@ -185,7 +185,7 @@ void V8ToGIArgument(GITypeInfo *type_info, GIArgument *arg, Handle<Value> value,
     case GI_TYPE_TAG_ARRAY:
         {
             GIArrayType array_type = g_type_info_get_array_type (type_info);
-            GArray *garray = V8ToGArray (type_info, value);
+            GArray *garray = V8ToGArray (isolate, type_info, value);
 
             switch (array_type) {
             case GI_ARRAY_TYPE_C:
@@ -256,24 +256,24 @@ void V8ToGValue(GValue *gvalue, Handle<Value> value) {
     }
 }
 
-Handle<Value> GValueToV8(const GValue *gvalue) {
+Handle<Value> GValueToV8(Isolate *isolate, const GValue *gvalue) {
     if (G_VALUE_HOLDS_BOOLEAN (gvalue)) {
         if (g_value_get_boolean (gvalue))
-            return True ();
+            return True (isolate);
         else
-            return False ();
+            return False (isolate);
     } else if (G_VALUE_HOLDS_INT (gvalue)) {
-        return Integer::New (g_value_get_int (gvalue));
+        return Integer::New (isolate, g_value_get_int (gvalue));
     } else if (G_VALUE_HOLDS_UINT (gvalue)) {
-        return Integer::NewFromUnsigned (g_value_get_uint (gvalue));
+        return Integer::NewFromUnsigned (isolate, g_value_get_uint (gvalue));
     } else if (G_VALUE_HOLDS_FLOAT (gvalue)) {
-        return Number::New (g_value_get_float (gvalue));
+        return Number::New (isolate, g_value_get_float (gvalue));
     } else if (G_VALUE_HOLDS_DOUBLE (gvalue)) {
-        return Number::New (g_value_get_double (gvalue));
+        return Number::New (isolate, g_value_get_double (gvalue));
     } else if (G_VALUE_HOLDS_STRING (gvalue)) {
-        return String::New (g_value_get_string (gvalue));
+        return String::NewFromUtf8 (isolate, g_value_get_string (gvalue));
     } else if (G_VALUE_HOLDS_OBJECT (gvalue)) {
-        return WrapperFromGObject (G_OBJECT (g_value_get_object (gvalue)));
+        return WrapperFromGObject (isolate, G_OBJECT (g_value_get_object (gvalue)));
     } else {
         g_assert_not_reached ();
     }
diff --git a/src/value.h b/src/value.h
index 6fcd6cd..868aa8e 100644
--- a/src/value.h
+++ b/src/value.h
@@ -27,11 +27,11 @@
 
 namespace GNodeJS {
 
-v8::Handle<v8::Value> GIArgumentToV8(GITypeInfo *type_info, GIArgument *argument);
-void V8ToGIArgument(GITypeInfo *type_info, GIArgument *argument, v8::Handle<v8::Value> value, bool 
may_be_null);
+v8::Handle<v8::Value> GIArgumentToV8(v8::Isolate *isolate, GITypeInfo *type_info, GIArgument *argument);
+void V8ToGIArgument(v8::Isolate *isolate, GITypeInfo *type_info, GIArgument *argument, v8::Handle<v8::Value> 
value, bool may_be_null);
 void FreeGIArgument(GITypeInfo *type_info, GIArgument *argument);
 
 void V8ToGValue(GValue *gvalue, v8::Handle<v8::Value> value);
-v8::Handle<v8::Value> GValueToV8(const GValue *gvalue);
+v8::Handle<v8::Value> GValueToV8(v8::Isolate *isolate, const GValue *gvalue);
 
 };


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]