11cb0ef41Sopenharmony_ci#include <node.h>
21cb0ef41Sopenharmony_ci#include <v8.h>
31cb0ef41Sopenharmony_ci#include <uv.h>
41cb0ef41Sopenharmony_ci#include <assert.h>
51cb0ef41Sopenharmony_ci#include <stdio.h>
61cb0ef41Sopenharmony_ci#include <stdlib.h>
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciusing v8::Context;
91cb0ef41Sopenharmony_ciusing v8::Function;
101cb0ef41Sopenharmony_ciusing v8::HandleScope;
111cb0ef41Sopenharmony_ciusing v8::Isolate;
121cb0ef41Sopenharmony_ciusing v8::Local;
131cb0ef41Sopenharmony_ciusing v8::MaybeLocal;
141cb0ef41Sopenharmony_ciusing v8::Object;
151cb0ef41Sopenharmony_ciusing v8::String;
161cb0ef41Sopenharmony_ciusing v8::Value;
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_cisize_t count = 0;
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_cistruct statically_allocated {
211cb0ef41Sopenharmony_ci  statically_allocated() {
221cb0ef41Sopenharmony_ci    assert(count == 0);
231cb0ef41Sopenharmony_ci    printf("ctor ");
241cb0ef41Sopenharmony_ci  }
251cb0ef41Sopenharmony_ci  ~statically_allocated() {
261cb0ef41Sopenharmony_ci    assert(count == 0);
271cb0ef41Sopenharmony_ci    printf("dtor ");
281cb0ef41Sopenharmony_ci  }
291cb0ef41Sopenharmony_ci} var;
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_civoid Dummy(void*) {
321cb0ef41Sopenharmony_ci  assert(0);
331cb0ef41Sopenharmony_ci}
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_civoid Cleanup(void* str) {
361cb0ef41Sopenharmony_ci  printf("%s ", static_cast<const char*>(str));
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  // Check that calling into JS fails.
391cb0ef41Sopenharmony_ci  Isolate* isolate = Isolate::GetCurrent();
401cb0ef41Sopenharmony_ci  HandleScope handle_scope(isolate);
411cb0ef41Sopenharmony_ci  assert(isolate->InContext());
421cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
431cb0ef41Sopenharmony_ci  MaybeLocal<Value> call_result =
441cb0ef41Sopenharmony_ci      context->Global()->Get(
451cb0ef41Sopenharmony_ci          context, String::NewFromUtf8Literal(isolate, "Object"))
461cb0ef41Sopenharmony_ci              .ToLocalChecked().As<Function>()->Call(
471cb0ef41Sopenharmony_ci                  context, v8::Null(isolate), 0, nullptr);
481cb0ef41Sopenharmony_ci  assert(call_result.IsEmpty());
491cb0ef41Sopenharmony_ci}
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_civoid Initialize(Local<Object> exports,
521cb0ef41Sopenharmony_ci                Local<Value> module,
531cb0ef41Sopenharmony_ci                Local<Context> context) {
541cb0ef41Sopenharmony_ci  node::AddEnvironmentCleanupHook(
551cb0ef41Sopenharmony_ci      context->GetIsolate(),
561cb0ef41Sopenharmony_ci      Cleanup,
571cb0ef41Sopenharmony_ci      const_cast<void*>(static_cast<const void*>("cleanup")));
581cb0ef41Sopenharmony_ci  node::AddEnvironmentCleanupHook(context->GetIsolate(), Dummy, nullptr);
591cb0ef41Sopenharmony_ci  node::RemoveEnvironmentCleanupHook(context->GetIsolate(), Dummy, nullptr);
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  if (getenv("addExtraItemToEventLoop") != nullptr) {
621cb0ef41Sopenharmony_ci    // Add an item to the event loop that we do not clean up in order to make
631cb0ef41Sopenharmony_ci    // sure that for the main thread, this addon's memory persists even after
641cb0ef41Sopenharmony_ci    // the Environment instance has been destroyed.
651cb0ef41Sopenharmony_ci    static uv_async_t extra_async;
661cb0ef41Sopenharmony_ci    uv_loop_t* loop = node::GetCurrentEventLoop(context->GetIsolate());
671cb0ef41Sopenharmony_ci    int err = uv_async_init(loop, &extra_async, [](uv_async_t*) {});
681cb0ef41Sopenharmony_ci    assert(err == 0);
691cb0ef41Sopenharmony_ci    uv_unref(reinterpret_cast<uv_handle_t*>(&extra_async));
701cb0ef41Sopenharmony_ci  }
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ciNODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME, Initialize)
74