| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 4b5eb7b commit 9a81921
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,99 @@ | |||
| 1 | + #include <node.h> | ||
| 2 | + #include <node_object_wrap.h> | ||
| 3 | + | ||
| 4 | + using v8::Context; | ||
| 5 | + using v8::Function; | ||
| 6 | + using v8::FunctionCallbackInfo; | ||
| 7 | + using v8::FunctionTemplate; | ||
| 8 | + using v8::Isolate; | ||
| 9 | + using v8::Local; | ||
| 10 | + using v8::Number; | ||
| 11 | + using v8::Object; | ||
| 12 | + using v8::ObjectTemplate; | ||
| 13 | + using v8::String; | ||
| 14 | + using v8::Value; | ||
| 15 | + | ||
| 16 | + class MyObject : public node::ObjectWrap { | ||
| 17 | + public: | ||
| 18 | + static void Init(v8::Local<v8::Object> exports); | ||
| 19 | + ~MyObject(); | ||
| 20 | + | ||
| 21 | + private: | ||
| 22 | + explicit MyObject(double value = 0); | ||
| 23 | + | ||
| 24 | + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 25 | + static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 26 | + | ||
| 27 | + double value_; | ||
| 28 | + }; | ||
| 29 | + | ||
| 30 | + MyObject::MyObject(double value) : value_(value) {} | ||
| 31 | + | ||
| 32 | + MyObject::~MyObject() {} | ||
| 33 | + | ||
| 34 | + void MyObject::Init(Local<Object> exports) { | ||
| 35 | + Isolate* isolate = Isolate::GetCurrent(); | ||
| 36 | + Local<Context> context = isolate->GetCurrentContext(); | ||
| 37 | + | ||
| 38 | + Local<ObjectTemplate> addon_data_tpl = ObjectTemplate::New(isolate); | ||
| 39 | + addon_data_tpl->SetInternalFieldCount(1); // 1 field for the MyObject::New() | ||
| 40 | + Local<Object> addon_data = | ||
| 41 | + addon_data_tpl->NewInstance(context).ToLocalChecked(); | ||
| 42 | + | ||
| 43 | + // Prepare constructor template | ||
| 44 | + Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New, addon_data); | ||
| 45 | + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked()); | ||
| 46 | + tpl->InstanceTemplate()->SetInternalFieldCount(1); | ||
| 47 | + | ||
| 48 | + // Prototype | ||
| 49 | + NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); | ||
| 50 | + | ||
| 51 | + Local<Function> constructor = tpl->GetFunction(context).ToLocalChecked(); | ||
| 52 | + addon_data->SetInternalField(0, constructor); | ||
| 53 | + exports | ||
| 54 | + ->Set(context, | ||
| 55 | + String::NewFromUtf8(isolate, "MyObject").ToLocalChecked(), | ||
| 56 | + constructor) | ||
| 57 | + .FromJust(); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + void MyObject::New(const FunctionCallbackInfo<Value>& args) { | ||
| 61 | + Isolate* isolate = args.GetIsolate(); | ||
| 62 | + Local<Context> context = isolate->GetCurrentContext(); | ||
| 63 | + | ||
| 64 | + if (args.IsConstructCall()) { | ||
| 65 | + // Invoked as constructor: `new MyObject(...)` | ||
| 66 | + double value = | ||
| 67 | + args[0]->IsUndefined() ? 0 : args[0]->NumberValue(context).FromMaybe(0); | ||
| 68 | + MyObject* obj = new MyObject(value); | ||
| 69 | + obj->Wrap(args.This()); | ||
| 70 | + args.GetReturnValue().Set(args.This()); | ||
| 71 | + } else { | ||
| 72 | + // Invoked as plain function `MyObject(...)`, turn into construct call. | ||
| 73 | + const int argc = 1; | ||
| 74 | + Local<Value> argv[argc] = {args[0]}; | ||
| 75 | + Local<Function> cons = args.Data() | ||
| 76 | + .As<Object>() | ||
| 77 | + ->GetInternalField(0) | ||
| 78 | + .As<Value>() | ||
| 79 | + .As<Function>(); | ||
| 80 | + Local<Object> result = | ||
| 81 | + cons->NewInstance(context, argc, argv).ToLocalChecked(); | ||
| 82 | + args.GetReturnValue().Set(result); | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) { | ||
| 87 | + Isolate* isolate = args.GetIsolate(); | ||
| 88 | + | ||
| 89 | + MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This()); | ||
| 90 | + obj->value_ += 1; | ||
| 91 | + | ||
| 92 | + args.GetReturnValue().Set(Number::New(isolate, obj->value_)); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + void InitAll(Local<Object> exports) { | ||
| 96 | + MyObject::Init(exports); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,9 @@ | |||
| 1 | + { | ||
| 2 | + 'targets': [ | ||
| 3 | + { | ||
| 4 | + 'target_name': 'binding', | ||
| 5 | + 'sources': [ 'binding.cc' ], | ||
| 6 | + 'includes': ['../common.gypi'], | ||
| 7 | + } | ||
| 8 | + ] | ||
| 9 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,20 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + const common = require('../../common'); | ||
| 3 | + const { isMainThread, Worker } = require('worker_threads'); | ||
| 4 | + | ||
| 5 | + if (!isMainThread) { | ||
| 6 | + const addon = require(`./build/${common.buildType}/binding`); | ||
| 7 | + | ||
| 8 | + | ||
| 9 | + // Create some garbage | ||
| 10 | + const arr = []; | ||
| 11 | + for (let i = 0; i < 1e5; i++) arr.push(`${i}`.repeat(100)); | ||
| 12 | + | ||
| 13 | + new addon.MyObject(10); | ||
| 14 | + | ||
| 15 | + // Should not segfault | ||
| 16 | + throw new Error('exit'); | ||
| 17 | + } else { | ||
| 18 | + const worker = new Worker(__filename); | ||
| 19 | + worker.on('error', common.mustCall()); | ||
| 20 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,15 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + const common = require('../../common'); | ||
| 3 | + const { isMainThread, Worker } = require('worker_threads'); | ||
| 4 | + | ||
| 5 | + if (!isMainThread) { | ||
| 6 | + const addon = require(`./build/${common.buildType}/binding`); | ||
| 7 | + | ||
| 8 | + new addon.MyObject(10); | ||
| 9 | + | ||
| 10 | + // Should not segfault | ||
| 11 | + throw new Error('exit'); | ||
| 12 | + } else { | ||
| 13 | + const worker = new Worker(__filename); | ||
| 14 | + worker.on('error', common.mustCall()); | ||
| 15 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments