| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ec3c39f commit 5340361
1 file changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -157,11 +157,11 @@ The context-aware addon can be structured to avoid global static data by | |||
| 157 | 157 | performing the following steps: | |
| 158 | 158 | ||
| 159 | 159 | * defining a class which will hold per-addon-instance data. Such | |
| 160 | - a class should include a `v8::Persistent<v8::Object>` which will hold a weak | ||
| 160 | + a class should include a `v8::Global<v8::Object>` which will hold a weak | ||
| 161 | 161 | reference to the addon's `exports` object. The callback associated with the weak | |
| 162 | 162 | reference will then destroy the instance of the class. | |
| 163 | 163 | * constructing an instance of this class in the addon initializer such that the | |
| 164 | - `v8::Persistent<v8::Object>` is set to the `exports` object. | ||
| 164 | + `v8::Global<v8::Object>` is set to the `exports` object. | ||
| 165 | 165 | * storing the instance of the class in a `v8::External`, and | |
| 166 | 166 | * passing the `v8::External` to all methods exposed to JavaScript by passing it | |
| 167 | 167 | to the `v8::FunctionTemplate` constructor which creates the native-backed | |
@@ -188,14 +188,6 @@ class AddonData { | |||
| 188 | 188 | exports_.SetWeak(this, DeleteMe, WeakCallbackType::kParameter); | |
| 189 | 189 | } | |
| 190 | 190 | ||
| 191 | - ~AddonData() { | ||
| 192 | - if (!exports_.IsEmpty()) { | ||
| 193 | - // Reset the reference to avoid leaking data. | ||
| 194 | - exports_.ClearWeak(); | ||
| 195 | - exports_.Reset(); | ||
| 196 | - } | ||
| 197 | - } | ||
| 198 | - | ||
| 199 | 191 | // Per-addon data. | |
| 200 | 192 | int call_count; | |
| 201 | 193 | ||
@@ -207,7 +199,7 @@ class AddonData { | |||
| 207 | 199 | ||
| 208 | 200 | // Weak handle to the "exports" object. An instance of this class will be | |
| 209 | 201 | // destroyed along with the exports object to which it is weakly bound. | |
| 210 | - v8::Persistent<v8::Object> exports_; | ||
| 202 | + v8::Global<v8::Object> exports_; | ||
| 211 | 203 | }; | |
| 212 | 204 | ||
| 213 | 205 | static void Method(const v8::FunctionCallbackInfo<v8::Value>& info) { | |
@@ -830,7 +822,7 @@ class MyObject : public node::ObjectWrap { | |||
| 830 | 822 | ||
| 831 | 823 | static void New(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 832 | 824 | static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 833 | - static v8::Persistent<v8::Function> constructor; | ||
| 825 | + | ||
| 834 | 826 | double value_; | |
| 835 | 827 | }; | |
| 836 | 828 | ||
@@ -858,12 +850,10 @@ using v8::Local; | |||
| 858 | 850 | using v8::NewStringType; | |
| 859 | 851 | using v8::Number; | |
| 860 | 852 | using v8::Object; | |
| 861 | - using v8::Persistent; | ||
| 853 | + using v8::ObjectTemplate; | ||
| 862 | 854 | using v8::String; | |
| 863 | 855 | using v8::Value; | |
| 864 | 856 | ||
| 865 | - Persistent<Function> MyObject::constructor; | ||
| 866 | - | ||
| 867 | 857 | MyObject::MyObject(double value) : value_(value) { | |
| 868 | 858 | } | |
| 869 | 859 | ||
@@ -872,21 +862,27 @@ MyObject::~MyObject() { | |||
| 872 | 862 | ||
| 873 | 863 | void MyObject::Init(Local<Object> exports) { | |
| 874 | 864 | Isolate* isolate = exports->GetIsolate(); | |
| 865 | + Local<Context> context = isolate->GetCurrentContext(); | ||
| 866 | + | ||
| 867 | + Local<ObjectTemplate> addon_data_tpl = ObjectTemplate::New(isolate); | ||
| 868 | + addon_data_tpl->SetInternalFieldCount(1); // 1 field for the MyObject::New() | ||
| 869 | + Local<Object> addon_data = | ||
| 870 | + addon_data_tpl->NewInstance(context).ToLocalChecked(); | ||
| 875 | 871 | ||
| 876 | 872 | // Prepare constructor template | |
| 877 | - Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); | ||
| 873 | + Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New, addon_data); | ||
| 878 | 874 | tpl->SetClassName(String::NewFromUtf8( | |
| 879 | 875 | isolate, "MyObject", NewStringType::kNormal).ToLocalChecked()); | |
| 880 | 876 | tpl->InstanceTemplate()->SetInternalFieldCount(1); | |
| 881 | 877 | ||
| 882 | 878 | // Prototype | |
| 883 | 879 | NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); | |
| 884 | 880 | ||
| 885 | - Local<Context> context = isolate->GetCurrentContext(); | ||
| 886 | - constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); | ||
| 881 | + Local<Function> constructor = tpl->GetFunction(context).ToLocalChecked(); | ||
| 882 | + addon_data->SetInternalField(0, constructor); | ||
| 887 | 883 | exports->Set(context, String::NewFromUtf8( | |
| 888 | 884 | isolate, "MyObject", NewStringType::kNormal).ToLocalChecked(), | |
| 889 | - tpl->GetFunction(context).ToLocalChecked()).FromJust(); | ||
| 885 | + constructor).FromJust(); | ||
| 890 | 886 | } | |
| 891 | 887 | ||
| 892 | 888 | void MyObject::New(const FunctionCallbackInfo<Value>& args) { | |
@@ -904,7 +900,8 @@ void MyObject::New(const FunctionCallbackInfo<Value>& args) { | |||
| 904 | 900 | // Invoked as plain function `MyObject(...)`, turn into construct call. | |
| 905 | 901 | const int argc = 1; | |
| 906 | 902 | Local<Value> argv[argc] = { args[0] }; | |
| 907 | - Local<Function> cons = Local<Function>::New(isolate, constructor); | ||
| 903 | + Local<Function> cons = | ||
| 904 | + args.Data().As<Object>()->GetInternalField(0).As<Function>(); | ||
| 908 | 905 | Local<Object> result = | |
| 909 | 906 | cons->NewInstance(context, argc, argv).ToLocalChecked(); | |
| 910 | 907 | args.GetReturnValue().Set(result); | |
@@ -1029,7 +1026,7 @@ class MyObject : public node::ObjectWrap { | |||
| 1029 | 1026 | ||
| 1030 | 1027 | static void New(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 1031 | 1028 | static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 1032 | - static v8::Persistent<v8::Function> constructor; | ||
| 1029 | + static v8::Global<v8::Function> constructor; | ||
| 1033 | 1030 | double value_; | |
| 1034 | 1031 | }; | |
| 1035 | 1032 | ||
@@ -1047,20 +1044,23 @@ The implementation in `myobject.cc` is similar to the previous example: | |||
| 1047 | 1044 | ||
| 1048 | 1045 | namespace demo { | |
| 1049 | 1046 | ||
| 1047 | + using node::AddEnvironmentCleanupHook; | ||
| 1050 | 1048 | using v8::Context; | |
| 1051 | 1049 | using v8::Function; | |
| 1052 | 1050 | using v8::FunctionCallbackInfo; | |
| 1053 | 1051 | using v8::FunctionTemplate; | |
| 1052 | + using v8::Global; | ||
| 1054 | 1053 | using v8::Isolate; | |
| 1055 | 1054 | using v8::Local; | |
| 1056 | 1055 | using v8::NewStringType; | |
| 1057 | 1056 | using v8::Number; | |
| 1058 | 1057 | using v8::Object; | |
| 1059 | - using v8::Persistent; | ||
| 1060 | 1058 | using v8::String; | |
| 1061 | 1059 | using v8::Value; | |
| 1062 | 1060 | ||
| 1063 | - Persistent<Function> MyObject::constructor; | ||
| 1061 | + // Warning! This is not thread-safe, this addon cannot be used for worker | ||
| 1062 | + // threads. | ||
| 1063 | + Global<Function> MyObject::constructor; | ||
| 1064 | 1064 | ||
| 1065 | 1065 | MyObject::MyObject(double value) : value_(value) { | |
| 1066 | 1066 | } | |
@@ -1080,6 +1080,10 @@ void MyObject::Init(Isolate* isolate) { | |||
| 1080 | 1080 | ||
| 1081 | 1081 | Local<Context> context = isolate->GetCurrentContext(); | |
| 1082 | 1082 | constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); | |
| 1083 | + | ||
| 1084 | + AddEnvironmentCleanupHook(isolate, [](void*) { | ||
| 1085 | + constructor.Reset(); | ||
| 1086 | + }, nullptr); | ||
| 1083 | 1087 | } | |
| 1084 | 1088 | ||
| 1085 | 1089 | void MyObject::New(const FunctionCallbackInfo<Value>& args) { | |
@@ -1246,7 +1250,7 @@ class MyObject : public node::ObjectWrap { | |||
| 1246 | 1250 | ~MyObject(); | |
| 1247 | 1251 | ||
| 1248 | 1252 | static void New(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 1249 | - static v8::Persistent<v8::Function> constructor; | ||
| 1253 | + static v8::Global<v8::Function> constructor; | ||
| 1250 | 1254 | double value_; | |
| 1251 | 1255 | }; | |
| 1252 | 1256 | ||
@@ -1264,19 +1268,22 @@ The implementation of `myobject.cc` is similar to before: | |||
| 1264 | 1268 | ||
| 1265 | 1269 | namespace demo { | |
| 1266 | 1270 | ||
| 1271 | + using node::AddEnvironmentCleanupHook; | ||
| 1267 | 1272 | using v8::Context; | |
| 1268 | 1273 | using v8::Function; | |
| 1269 | 1274 | using v8::FunctionCallbackInfo; | |
| 1270 | 1275 | using v8::FunctionTemplate; | |
| 1276 | + using v8::Global; | ||
| 1271 | 1277 | using v8::Isolate; | |
| 1272 | 1278 | using v8::Local; | |
| 1273 | 1279 | using v8::NewStringType; | |
| 1274 | 1280 | using v8::Object; | |
| 1275 | - using v8::Persistent; | ||
| 1276 | 1281 | using v8::String; | |
| 1277 | 1282 | using v8::Value; | |
| 1278 | 1283 | ||
| 1279 | - Persistent<Function> MyObject::constructor; | ||
| 1284 | + // Warning! This is not thread-safe, this addon cannot be used for worker | ||
| 1285 | + // threads. | ||
| 1286 | + Global<Function> MyObject::constructor; | ||
| 1280 | 1287 | ||
| 1281 | 1288 | MyObject::MyObject(double value) : value_(value) { | |
| 1282 | 1289 | } | |
@@ -1293,6 +1300,10 @@ void MyObject::Init(Isolate* isolate) { | |||
| 1293 | 1300 | ||
| 1294 | 1301 | Local<Context> context = isolate->GetCurrentContext(); | |
| 1295 | 1302 | constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); | |
| 1303 | + | ||
| 1304 | + AddEnvironmentCleanupHook(isolate, [](void*) { | ||
| 1305 | + constructor.Reset(); | ||
| 1306 | + }, nullptr); | ||
| 1296 | 1307 | } | |
| 1297 | 1308 | ||
| 1298 | 1309 | void MyObject::New(const FunctionCallbackInfo<Value>& args) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments