11cb0ef41Sopenharmony_ci#include "gtest/gtest.h"
21cb0ef41Sopenharmony_ci#include "node.h"
31cb0ef41Sopenharmony_ci#include "node_internals.h"
41cb0ef41Sopenharmony_ci#include "node_test_fixture.h"
51cb0ef41Sopenharmony_ci#include "req_wrap-inl.h"
61cb0ef41Sopenharmony_ci#include "tracing/agent.h"
71cb0ef41Sopenharmony_ci#include "v8.h"
81cb0ef41Sopenharmony_ci#include "v8abbr.h"
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciextern "C" {
111cb0ef41Sopenharmony_ciextern uintptr_t
121cb0ef41Sopenharmony_ci    nodedbg_offset_HandleWrap__handle_wrap_queue___ListNode_HandleWrap;
131cb0ef41Sopenharmony_ciextern uintptr_t
141cb0ef41Sopenharmony_ci    nodedbg_offset_Environment__handle_wrap_queue___Environment_HandleWrapQueue;
151cb0ef41Sopenharmony_ciextern int debug_symbols_generated;
161cb0ef41Sopenharmony_ciextern int nodedbg_const_ContextEmbedderIndex__kEnvironment__int;
171cb0ef41Sopenharmony_ciextern int nodedbg_const_BaseObject__kInternalFieldCount__int;
181cb0ef41Sopenharmony_ciextern uintptr_t
191cb0ef41Sopenharmony_ci    nodedbg_offset_Environment_HandleWrapQueue__head___ListNode_HandleWrap;
201cb0ef41Sopenharmony_ciextern uintptr_t
211cb0ef41Sopenharmony_ci    nodedbg_offset_Environment__req_wrap_queue___Environment_ReqWrapQueue;
221cb0ef41Sopenharmony_ciextern uintptr_t nodedbg_offset_ExternalString__data__uintptr_t;
231cb0ef41Sopenharmony_ciextern uintptr_t nodedbg_offset_ListNode_ReqWrap__prev___uintptr_t;
241cb0ef41Sopenharmony_ciextern uintptr_t nodedbg_offset_ListNode_ReqWrap__next___uintptr_t;
251cb0ef41Sopenharmony_ciextern uintptr_t nodedbg_offset_ReqWrap__req_wrap_queue___ListNode_ReqWrapQueue;
261cb0ef41Sopenharmony_ciextern uintptr_t nodedbg_offset_ListNode_HandleWrap__prev___uintptr_t;
271cb0ef41Sopenharmony_ciextern uintptr_t nodedbg_offset_ListNode_HandleWrap__next___uintptr_t;
281cb0ef41Sopenharmony_ciextern uintptr_t
291cb0ef41Sopenharmony_ci    nodedbg_offset_Environment_ReqWrapQueue__head___ListNode_ReqWrapQueue;
301cb0ef41Sopenharmony_ciextern uintptr_t
311cb0ef41Sopenharmony_ci    nodedbg_offset_BaseObject__persistent_handle___v8_Persistent_v8_Object;
321cb0ef41Sopenharmony_ci}
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ciclass DebugSymbolsTest : public EnvironmentTestFixture {};
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciclass TestHandleWrap : public node::HandleWrap {
391cb0ef41Sopenharmony_ci public:
401cb0ef41Sopenharmony_ci  SET_NO_MEMORY_INFO()
411cb0ef41Sopenharmony_ci  SET_MEMORY_INFO_NAME(TestHandleWrap)
421cb0ef41Sopenharmony_ci  SET_SELF_SIZE(TestHandleWrap)
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  TestHandleWrap(node::Environment* env,
451cb0ef41Sopenharmony_ci                 v8::Local<v8::Object> object,
461cb0ef41Sopenharmony_ci                 uv_tcp_t* handle)
471cb0ef41Sopenharmony_ci      : node::HandleWrap(env,
481cb0ef41Sopenharmony_ci                         object,
491cb0ef41Sopenharmony_ci                         reinterpret_cast<uv_handle_t*>(handle),
501cb0ef41Sopenharmony_ci                         node::AsyncWrap::PROVIDER_TCPWRAP) {}
511cb0ef41Sopenharmony_ci};
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ciclass TestReqWrap : public node::ReqWrap<uv_req_t> {
551cb0ef41Sopenharmony_ci public:
561cb0ef41Sopenharmony_ci  SET_NO_MEMORY_INFO()
571cb0ef41Sopenharmony_ci  SET_MEMORY_INFO_NAME(TestReqWrap)
581cb0ef41Sopenharmony_ci  SET_SELF_SIZE(TestReqWrap)
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  TestReqWrap(node::Environment* env, v8::Local<v8::Object> object)
611cb0ef41Sopenharmony_ci      : node::ReqWrap<uv_req_t>(env,
621cb0ef41Sopenharmony_ci                                object,
631cb0ef41Sopenharmony_ci                                node::AsyncWrap::PROVIDER_FSREQCALLBACK) {}
641cb0ef41Sopenharmony_ci};
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ciTEST_F(DebugSymbolsTest, ContextEmbedderEnvironmentIndex) {
671cb0ef41Sopenharmony_ci  int kEnvironmentIndex = node::ContextEmbedderIndex::kEnvironment;
681cb0ef41Sopenharmony_ci  EXPECT_EQ(nodedbg_const_ContextEmbedderIndex__kEnvironment__int,
691cb0ef41Sopenharmony_ci            kEnvironmentIndex);
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciTEST_F(DebugSymbolsTest, BaseObjectkInternalFieldCount) {
731cb0ef41Sopenharmony_ci  int kInternalFieldCount = node::BaseObject::kInternalFieldCount;
741cb0ef41Sopenharmony_ci  EXPECT_EQ(nodedbg_const_BaseObject__kInternalFieldCount__int,
751cb0ef41Sopenharmony_ci            kInternalFieldCount);
761cb0ef41Sopenharmony_ci}
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ciTEST_F(DebugSymbolsTest, ExternalStringDataOffset) {
791cb0ef41Sopenharmony_ci  EXPECT_EQ(nodedbg_offset_ExternalString__data__uintptr_t,
801cb0ef41Sopenharmony_ci            NODE_OFF_EXTSTR_DATA);
811cb0ef41Sopenharmony_ci}
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ciclass DummyBaseObject : public node::BaseObject {
841cb0ef41Sopenharmony_ci public:
851cb0ef41Sopenharmony_ci  DummyBaseObject(node::Environment* env, v8::Local<v8::Object> obj) :
861cb0ef41Sopenharmony_ci    BaseObject(env, obj) {}
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  SET_NO_MEMORY_INFO()
891cb0ef41Sopenharmony_ci  SET_MEMORY_INFO_NAME(DummyBaseObject)
901cb0ef41Sopenharmony_ci  SET_SELF_SIZE(DummyBaseObject)
911cb0ef41Sopenharmony_ci};
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ciTEST_F(DebugSymbolsTest, BaseObjectPersistentHandle) {
941cb0ef41Sopenharmony_ci  const v8::HandleScope handle_scope(isolate_);
951cb0ef41Sopenharmony_ci  const Argv argv;
961cb0ef41Sopenharmony_ci  Env env{handle_scope, argv};
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  v8::Local<v8::ObjectTemplate> obj_templ = v8::ObjectTemplate::New(isolate_);
991cb0ef41Sopenharmony_ci  obj_templ->SetInternalFieldCount(
1001cb0ef41Sopenharmony_ci      nodedbg_const_BaseObject__kInternalFieldCount__int);
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  v8::Local<v8::Object> object =
1031cb0ef41Sopenharmony_ci      obj_templ->NewInstance(env.context()).ToLocalChecked();
1041cb0ef41Sopenharmony_ci  node::BaseObjectPtr<DummyBaseObject> obj =
1051cb0ef41Sopenharmony_ci      node::MakeDetachedBaseObject<DummyBaseObject>(*env, object);
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  auto expected = reinterpret_cast<uintptr_t>(&obj->persistent());
1081cb0ef41Sopenharmony_ci  auto calculated = reinterpret_cast<uintptr_t>(obj.get()) +
1091cb0ef41Sopenharmony_ci      nodedbg_offset_BaseObject__persistent_handle___v8_Persistent_v8_Object;
1101cb0ef41Sopenharmony_ci  EXPECT_EQ(expected, calculated);
1111cb0ef41Sopenharmony_ci}
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ciTEST_F(DebugSymbolsTest, EnvironmentHandleWrapQueue) {
1151cb0ef41Sopenharmony_ci  const v8::HandleScope handle_scope(isolate_);
1161cb0ef41Sopenharmony_ci  const Argv argv;
1171cb0ef41Sopenharmony_ci  Env env{handle_scope, argv};
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  auto expected = reinterpret_cast<uintptr_t>((*env)->handle_wrap_queue());
1201cb0ef41Sopenharmony_ci  auto calculated = reinterpret_cast<uintptr_t>(*env) +
1211cb0ef41Sopenharmony_ci      nodedbg_offset_Environment__handle_wrap_queue___Environment_HandleWrapQueue;  // NOLINT(whitespace/line_length)
1221cb0ef41Sopenharmony_ci  EXPECT_EQ(expected, calculated);
1231cb0ef41Sopenharmony_ci}
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ciTEST_F(DebugSymbolsTest, EnvironmentReqWrapQueue) {
1261cb0ef41Sopenharmony_ci  const v8::HandleScope handle_scope(isolate_);
1271cb0ef41Sopenharmony_ci  const Argv argv;
1281cb0ef41Sopenharmony_ci  Env env{handle_scope, argv};
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  auto expected = reinterpret_cast<uintptr_t>((*env)->req_wrap_queue());
1311cb0ef41Sopenharmony_ci  auto calculated = reinterpret_cast<uintptr_t>(*env) +
1321cb0ef41Sopenharmony_ci      nodedbg_offset_Environment__req_wrap_queue___Environment_ReqWrapQueue;
1331cb0ef41Sopenharmony_ci  EXPECT_EQ(expected, calculated);
1341cb0ef41Sopenharmony_ci}
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ciTEST_F(DebugSymbolsTest, HandleWrapList) {
1371cb0ef41Sopenharmony_ci  const v8::HandleScope handle_scope(isolate_);
1381cb0ef41Sopenharmony_ci  const Argv argv;
1391cb0ef41Sopenharmony_ci  Env env{handle_scope, argv};
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci  auto queue = reinterpret_cast<uintptr_t>((*env)->handle_wrap_queue());
1421cb0ef41Sopenharmony_ci  auto head = queue +
1431cb0ef41Sopenharmony_ci      nodedbg_offset_Environment_HandleWrapQueue__head___ListNode_HandleWrap;
1441cb0ef41Sopenharmony_ci  auto tail = head + nodedbg_offset_ListNode_HandleWrap__prev___uintptr_t;
1451cb0ef41Sopenharmony_ci  tail = *reinterpret_cast<uintptr_t*>(tail);
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci  uv_tcp_t handle;
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci  auto obj_template = v8::FunctionTemplate::New(isolate_);
1501cb0ef41Sopenharmony_ci  obj_template->InstanceTemplate()->SetInternalFieldCount(
1511cb0ef41Sopenharmony_ci      nodedbg_const_BaseObject__kInternalFieldCount__int);
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  v8::Local<v8::Object> object = obj_template->GetFunction(env.context())
1541cb0ef41Sopenharmony_ci                                     .ToLocalChecked()
1551cb0ef41Sopenharmony_ci                                     ->NewInstance(env.context())
1561cb0ef41Sopenharmony_ci                                     .ToLocalChecked();
1571cb0ef41Sopenharmony_ci  TestHandleWrap obj(*env, object, &handle);
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci  auto last = tail + nodedbg_offset_ListNode_HandleWrap__next___uintptr_t;
1601cb0ef41Sopenharmony_ci  last = *reinterpret_cast<uintptr_t*>(last);
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci  auto expected = reinterpret_cast<uintptr_t>(&obj);
1631cb0ef41Sopenharmony_ci  auto calculated =
1641cb0ef41Sopenharmony_ci      last - nodedbg_offset_HandleWrap__handle_wrap_queue___ListNode_HandleWrap;
1651cb0ef41Sopenharmony_ci  EXPECT_EQ(expected, calculated);
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci  obj.persistent().Reset();  // ~HandleWrap() expects an empty handle.
1681cb0ef41Sopenharmony_ci}
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ciTEST_F(DebugSymbolsTest, ReqWrapList) {
1711cb0ef41Sopenharmony_ci  const v8::HandleScope handle_scope(isolate_);
1721cb0ef41Sopenharmony_ci  const Argv argv;
1731cb0ef41Sopenharmony_ci  Env env{handle_scope, argv};
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci  auto queue = reinterpret_cast<uintptr_t>((*env)->req_wrap_queue());
1761cb0ef41Sopenharmony_ci  auto head =
1771cb0ef41Sopenharmony_ci      queue +
1781cb0ef41Sopenharmony_ci      nodedbg_offset_Environment_ReqWrapQueue__head___ListNode_ReqWrapQueue;
1791cb0ef41Sopenharmony_ci  auto tail = head + nodedbg_offset_ListNode_ReqWrap__prev___uintptr_t;
1801cb0ef41Sopenharmony_ci  tail = *reinterpret_cast<uintptr_t*>(tail);
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci  auto obj_template = v8::FunctionTemplate::New(isolate_);
1831cb0ef41Sopenharmony_ci  obj_template->InstanceTemplate()->SetInternalFieldCount(
1841cb0ef41Sopenharmony_ci      nodedbg_const_BaseObject__kInternalFieldCount__int);
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ci  v8::Local<v8::Object> object = obj_template->GetFunction(env.context())
1871cb0ef41Sopenharmony_ci                                     .ToLocalChecked()
1881cb0ef41Sopenharmony_ci                                     ->NewInstance(env.context())
1891cb0ef41Sopenharmony_ci                                     .ToLocalChecked();
1901cb0ef41Sopenharmony_ci  TestReqWrap obj(*env, object);
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ci  // NOTE (mmarchini): Workaround to fix failing tests on ARM64 machines with
1931cb0ef41Sopenharmony_ci  // older GCC. Should be removed once we upgrade the GCC version used on our
1941cb0ef41Sopenharmony_ci  // ARM64 CI machinies.
1951cb0ef41Sopenharmony_ci  for (auto it : *(*env)->req_wrap_queue()) (void) &it;
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci  volatile uintptr_t last =
1981cb0ef41Sopenharmony_ci      tail + nodedbg_offset_ListNode_ReqWrap__next___uintptr_t;
1991cb0ef41Sopenharmony_ci  last = *reinterpret_cast<uintptr_t*>(last);
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ci  auto expected = reinterpret_cast<uintptr_t>(&obj);
2021cb0ef41Sopenharmony_ci  auto calculated =
2031cb0ef41Sopenharmony_ci      last - nodedbg_offset_ReqWrap__req_wrap_queue___ListNode_ReqWrapQueue;
2041cb0ef41Sopenharmony_ci  EXPECT_EQ(expected, calculated);
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci  obj.Dispatched();
2071cb0ef41Sopenharmony_ci}
208