Skip to content

Commit fceb3ff

Browse files
committed
src: add utilities for cppgc classes
1 parent 78855fd commit fceb3ff

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

node.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@
189189
'src/cleanup_queue-inl.h',
190190
'src/connect_wrap.h',
191191
'src/connection_wrap.h',
192+
'src/cppgc_helpers.h',
192193
'src/dataqueue/queue.h',
193194
'src/debug_utils.h',
194195
'src/debug_utils-inl.h',

src/cppgc_helpers.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#ifndef SRC_CPPGC_HELPERS_H_
2+
#define SRC_CPPGC_HELPERS_H_
3+
4+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5+
6+
#include "cppgc/garbage-collected.h"
7+
#include "env.h"
8+
#include "memory_tracker.h"
9+
#include "v8-cppgc.h"
10+
#include "v8.h"
11+
12+
namespace node {
13+
14+
#define ASSIGN_OR_RETURN_UNWRAP_CPPGC(ptr, obj, ...) \
15+
do { \
16+
DCHECK_GE(obj->InternalFieldCount(), kInternalFieldCount); \
17+
*ptr = static_cast<typename std::remove_reference<decltype(*ptr)>::type>( \
18+
obj->GetAlignedPointerFromInternalField(kSlot)); \
19+
if (*ptr == nullptr) return __VA_ARGS__; \
20+
} while (0)
21+
22+
#define CPPGC_MIXIN_FIELDS() \
23+
Environment* env_; \
24+
v8::TracedReference<v8::Object> traced_reference_;
25+
26+
class CppgcMixin {
27+
public:
28+
enum { kEmbedderType, kSlot, kInternalFieldCount };
29+
template <typename T>
30+
static T* Unwrap(v8::Local<v8::Object> obj) {
31+
DCHECK_GE(obj->InternalFieldCount(), T::kInternalFieldCount);
32+
T* ptr = static_cast<T*>(obj->GetAlignedPointerFromInternalField(T::kSlot));
33+
return ptr;
34+
}
35+
};
36+
37+
#define CPPGC_MIXIN_METHODS() \
38+
v8::Local<v8::Object> object() const { \
39+
return traced_reference_.Get(env_->isolate()); \
40+
} \
41+
Environment* env() const { return env_; }
42+
43+
#define TRACE_CPPGC_OBJECT(visitor) visitor->Trace(traced_reference_);
44+
45+
#define INITIALIZE_CPPGC_OBJECT(env, obj, ptr) \
46+
env_ = env; \
47+
traced_reference_ = v8::TracedReference<v8::Object>(env->isolate(), obj); \
48+
SetCppgcReference(env->isolate(), obj, ptr);
49+
50+
#define DEFAULT_CPPGC_TRACE() \
51+
void Trace(cppgc::Visitor* visitor) const { TRACE_CPPGC_OBJECT(visitor) }
52+
53+
} // namespace node
54+
55+
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
56+
57+
#endif // SRC_BASE_OBJECT_H_

src/util.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,30 @@ void SetConstructorFunction(v8::Isolate* isolate,
969969
SetConstructorFunctionFlag flag =
970970
SetConstructorFunctionFlag::SET_CLASS_NAME);
971971

972+
#define GET_OR_SET_CONSTRUCTOR_TEMPLATE(tmpl, isolate_data, id, name) \
973+
do { \
974+
v8::Isolate* isolate = isolate_data->isolate(); \
975+
tmpl = isolate_data->id##_constructor_template(); \
976+
if (tmpl.IsEmpty()) { \
977+
tmpl = v8::FunctionTemplate::New(isolate, New); \
978+
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount); \
979+
tmpl->SetClassName(FIXED_ONE_BYTE_STRING(isolate, #name)); \
980+
isolate_data->set_##id##_constructor_template(tmpl); \
981+
} \
982+
} while (0);
983+
984+
#define CONSTRUCTOR_TEMPLATE_GENERATOR(id, name) \
985+
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( \
986+
IsolateData* isolate_data) { \
987+
v8::Local<v8::FunctionTemplate> tmpl; \
988+
GET_OR_SET_CONSTRUCTOR_TEMPLATE(tmpl, isolate_data, id, name); \
989+
return tmpl; \
990+
}
991+
992+
#define DECL_CONSTRUCTOR_TEMPLATE_GENERATOR() \
993+
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( \
994+
IsolateData* isolate_data);
995+
972996
// Like RAIIIsolate, except doesn't enter the isolate while it's in scope.
973997
class RAIIIsolateWithoutEntering {
974998
public:

0 commit comments

Comments
 (0)