1 #include <node.h>
2 #include <v8.h>
3 #include <uv.h>
4 #include <assert.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 using v8::Context;
9 using v8::Function;
10 using v8::HandleScope;
11 using v8::Isolate;
12 using v8::Local;
13 using v8::MaybeLocal;
14 using v8::Object;
15 using v8::String;
16 using v8::Value;
17
18 size_t count = 0;
19
20 struct statically_allocated {
statically_allocatedstatically_allocated21 statically_allocated() {
22 assert(count == 0);
23 printf("ctor ");
24 }
~statically_allocatedstatically_allocated25 ~statically_allocated() {
26 assert(count == 0);
27 printf("dtor ");
28 }
29 } var;
30
Dummy(void *)31 void Dummy(void*) {
32 assert(0);
33 }
34
Cleanup(void * str)35 void Cleanup(void* str) {
36 printf("%s ", static_cast<const char*>(str));
37
38 // Check that calling into JS fails.
39 Isolate* isolate = Isolate::GetCurrent();
40 HandleScope handle_scope(isolate);
41 assert(isolate->InContext());
42 Local<Context> context = isolate->GetCurrentContext();
43 MaybeLocal<Value> call_result =
44 context->Global()->Get(
45 context, String::NewFromUtf8Literal(isolate, "Object"))
46 .ToLocalChecked().As<Function>()->Call(
47 context, v8::Null(isolate), 0, nullptr);
48 assert(call_result.IsEmpty());
49 }
50
Initialize(Local<Object> exports,Local<Value> module,Local<Context> context)51 void Initialize(Local<Object> exports,
52 Local<Value> module,
53 Local<Context> context) {
54 node::AddEnvironmentCleanupHook(
55 context->GetIsolate(),
56 Cleanup,
57 const_cast<void*>(static_cast<const void*>("cleanup")));
58 node::AddEnvironmentCleanupHook(context->GetIsolate(), Dummy, nullptr);
59 node::RemoveEnvironmentCleanupHook(context->GetIsolate(), Dummy, nullptr);
60
61 if (getenv("addExtraItemToEventLoop") != nullptr) {
62 // Add an item to the event loop that we do not clean up in order to make
63 // sure that for the main thread, this addon's memory persists even after
64 // the Environment instance has been destroyed.
65 static uv_async_t extra_async;
66 uv_loop_t* loop = node::GetCurrentEventLoop(context->GetIsolate());
67 int err = uv_async_init(loop, &extra_async, [](uv_async_t*) {});
68 assert(err == 0);
69 uv_unref(reinterpret_cast<uv_handle_t*>(&extra_async));
70 }
71 }
72
73 NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME, Initialize)
74