Skip to content

Commit ea7bc69

Browse files
committed
remove C++ API wrappers and tests
1 parent 6e04ec6 commit ea7bc69

13 files changed

+276
-2284
lines changed

node.gyp

-9
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@
241241
'src/node_dir.h',
242242
'src/node_dotenv.h',
243243
'src/node_embedding_api.h',
244-
'src/node_embedding_api_cpp.h',
245244
'src/node_errors.h',
246245
'src/node_exit_code.h',
247246
'src/node_external_reference.h',
@@ -1278,14 +1277,6 @@
12781277
'test/embedding/embedtest_c_api_run_main.c',
12791278
'test/embedding/embedtest_c_api_threading.c',
12801279
'test/embedding/embedtest_c_api.c',
1281-
'test/embedding/embedtest_c_cpp_api_common.cc',
1282-
'test/embedding/embedtest_c_cpp_api_common.h',
1283-
'test/embedding/embedtest_c_cpp_api_env.cc',
1284-
'test/embedding/embedtest_c_cpp_api_modules.cc',
1285-
'test/embedding/embedtest_c_cpp_api_preload.cc',
1286-
'test/embedding/embedtest_c_cpp_api_run_main.cc',
1287-
'test/embedding/embedtest_c_cpp_api_threading.cc',
1288-
'test/embedding/embedtest_c_cpp_api.cc',
12891280
'test/embedding/embedtest_main.cc',
12901281
],
12911282

src/node_embedding_api.cc

+276-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "node_version.h" // define NODE_VERSION first
22

3-
#include "node_embedding_api_cpp.h"
3+
#include "node_embedding_api.h"
44

55
#include "env-inl.h"
66
#include "js_native_api_v8.h"
@@ -92,6 +92,281 @@ v8::Maybe<ExitCode> SpinEventLoopWithoutCleanup(Environment* env,
9292

9393
namespace node::embedding {
9494

95+
// Move-only pointer wrapper.
96+
// The class does not own the pointer and does not delete it.
97+
// It simplifies implementation of the C++ API classes that wrap pointers.
98+
template <typename TPointer>
99+
class NodePointer {
100+
public:
101+
NodePointer() = default;
102+
103+
explicit NodePointer(TPointer ptr) : ptr_(ptr) {}
104+
105+
NodePointer(const NodePointer&) = delete;
106+
NodePointer& operator=(const NodePointer&) = delete;
107+
108+
NodePointer(NodePointer&& other) noexcept
109+
: ptr_(std::exchange(other.ptr_, nullptr)) {}
110+
111+
NodePointer& operator=(NodePointer&& other) noexcept {
112+
if (this != &other) {
113+
ptr_ = std::exchange(other.ptr_, nullptr);
114+
}
115+
return *this;
116+
}
117+
118+
NodePointer& operator=(std::nullptr_t) {
119+
ptr_ = nullptr;
120+
return *this;
121+
}
122+
123+
TPointer ptr() const { return ptr_; }
124+
125+
explicit operator bool() const { return ptr_ != nullptr; }
126+
127+
private:
128+
TPointer ptr_{};
129+
};
130+
131+
// A helper class to convert std::vector<std::string> to an array of C strings.
132+
// If the number of strings is less than kInplaceBufferSize, the strings are
133+
// stored in the inplace_buffer_ array. Otherwise, the strings are stored in the
134+
// allocated_buffer_ array.
135+
// Ideally the class must be allocated on the stack.
136+
// In any case it must not outlive the passed vector since it keeps only the
137+
// string pointers returned by std::string::c_str() method.
138+
template <size_t kInplaceBufferSize = 32>
139+
class NodeCStringArray {
140+
public:
141+
NodeCStringArray() = default;
142+
143+
explicit NodeCStringArray(const std::vector<std::string>& strings) noexcept
144+
: size_(strings.size()) {
145+
if (size_ <= inplace_buffer_.size()) {
146+
c_strs_ = inplace_buffer_.data();
147+
} else {
148+
allocated_buffer_ = std::make_unique<const char*[]>(size_);
149+
c_strs_ = allocated_buffer_.get();
150+
}
151+
for (size_t i = 0; i < size_; ++i) {
152+
c_strs_[i] = strings[i].c_str();
153+
}
154+
}
155+
156+
NodeCStringArray(const NodeCStringArray&) = delete;
157+
NodeCStringArray& operator=(const NodeCStringArray&) = delete;
158+
159+
NodeCStringArray(NodeCStringArray&& other) noexcept
160+
: size_(std::exchange(other.size_, 0)),
161+
c_strs_(std::exchange(other.c_strs_, 0)),
162+
allocated_buffer_(std::exchange(other.allocated_buffer_, nullptr)) {
163+
if (size_ <= inplace_buffer_.size()) {
164+
c_strs_ = inplace_buffer_.data();
165+
std::memcpy(inplace_buffer_.data(),
166+
other.inplace_buffer_.data(),
167+
size_ * sizeof(const char*));
168+
}
169+
}
170+
171+
NodeCStringArray& operator=(NodeCStringArray&& other) noexcept {
172+
if (this != &other) {
173+
size_ = std::exchange(other.size_, 0);
174+
c_strs_ = std::exchange(other.c_strs_, nullptr);
175+
allocated_buffer_ = std::exchange(other.allocated_buffer_, nullptr);
176+
if (size_ <= inplace_buffer_.size()) {
177+
c_strs_ = inplace_buffer_.data();
178+
std::memcpy(inplace_buffer_.data(),
179+
other.inplace_buffer_.data(),
180+
size_ * sizeof(const char*));
181+
}
182+
}
183+
return *this;
184+
}
185+
186+
int32_t size() const { return static_cast<int32_t>(size_); }
187+
const char** c_strs() const { return c_strs_; }
188+
189+
private:
190+
size_t size_{};
191+
const char** c_strs_{};
192+
std::array<const char*, kInplaceBufferSize> inplace_buffer_;
193+
std::unique_ptr<const char*[]> allocated_buffer_;
194+
};
195+
196+
template <typename TCallback, typename TFunctor, typename TEnable = void>
197+
class NodeFunctorInvoker;
198+
199+
template <typename TCallback>
200+
class NodeFunctorRef;
201+
202+
template <typename TResult, typename... TArgs>
203+
class NodeFunctorRef<TResult (*)(void*, TArgs...)> {
204+
using TCallback = TResult (*)(void*, TArgs...);
205+
206+
public:
207+
NodeFunctorRef(std::nullptr_t) {}
208+
209+
NodeFunctorRef(TCallback callback, void* data)
210+
: callback_(callback), data_(data) {}
211+
212+
template <typename TFunctor>
213+
NodeFunctorRef(TFunctor&& functor)
214+
: callback_(&NodeFunctorInvoker<TCallback, TFunctor>::Invoke),
215+
data_(&functor) {}
216+
217+
NodeFunctorRef(NodeFunctorRef&& other) = default;
218+
NodeFunctorRef& operator=(NodeFunctorRef&& other) = default;
219+
220+
TCallback callback() const { return callback_.ptr(); }
221+
222+
void* data() const { return data_.ptr(); }
223+
224+
explicit operator bool() const { return static_cast<bool>(callback_); }
225+
226+
private:
227+
NodePointer<TCallback> callback_;
228+
NodePointer<void*> data_;
229+
};
230+
231+
template <typename TCallback>
232+
class NodeFunctor;
233+
234+
template <typename TResult, typename... TArgs>
235+
class NodeFunctor<TResult (*)(void*, TArgs...)> {
236+
using TCallback = TResult (*)(void*, TArgs...);
237+
238+
public:
239+
NodeFunctor() = default;
240+
NodeFunctor(std::nullptr_t) {}
241+
242+
NodeFunctor(TCallback callback,
243+
void* data,
244+
node_embedding_data_release_callback data_release)
245+
: callback_(callback), data_(data), data_release_(data_release) {}
246+
247+
// TODO: add overload for stateless lambdas.
248+
template <typename TFunctor>
249+
NodeFunctor(TFunctor&& functor)
250+
: callback_(&NodeFunctorInvoker<TCallback, TFunctor>::Invoke),
251+
data_(new TFunctor(std::forward<TFunctor>(functor))),
252+
data_release_(&ReleaseFunctor<TFunctor>) {}
253+
254+
NodeFunctor(NodeFunctor&& other) = default;
255+
NodeFunctor& operator=(NodeFunctor&& other) = default;
256+
257+
TCallback callback() const { return callback_.ptr(); }
258+
259+
void* data() const { return data_.ptr(); }
260+
261+
node_embedding_data_release_callback data_release() const {
262+
return data_release_.ptr();
263+
}
264+
265+
explicit operator bool() const { return static_cast<bool>(callback_); }
266+
267+
TResult operator()(TArgs... args) const {
268+
return (*callback_.ptr())(data_.ptr(), args...);
269+
}
270+
271+
private:
272+
template <typename TFunctor>
273+
static NodeStatus ReleaseFunctor(void* data) {
274+
// TODO: Handle exceptions.
275+
delete reinterpret_cast<TFunctor*>(data);
276+
return NodeStatus::kOk;
277+
}
278+
279+
private:
280+
NodePointer<TCallback> callback_;
281+
NodePointer<void*> data_;
282+
NodePointer<node_embedding_data_release_callback> data_release_;
283+
};
284+
285+
static std::string NodeFormatStringHelper(const char* format, va_list args) {
286+
va_list args2; // Required for some compilers like GCC since we go over the
287+
// args twice.
288+
va_copy(args2, args);
289+
std::string result(std::vsnprintf(nullptr, 0, format, args), '\0');
290+
std::vsnprintf(&result[0], result.size() + 1, format, args2);
291+
va_end(args2);
292+
return result;
293+
}
294+
295+
static std::string NodeFormatString(const char* format, ...) {
296+
va_list args;
297+
va_start(args, format);
298+
std::string result = NodeFormatStringHelper(format, args);
299+
va_end(args);
300+
return result;
301+
}
302+
303+
class NodeErrorInfo {
304+
public:
305+
static const char* GetLastErrorMessage() {
306+
return node_embedding_last_error_message_get();
307+
}
308+
309+
static void SetLastErrorMessage(const char* message) {
310+
return node_embedding_last_error_message_set(message);
311+
}
312+
313+
static void SetLastErrorMessage(std::string_view message,
314+
std::string_view filename,
315+
int32_t line) {
316+
SetLastErrorMessage(
317+
NodeFormatString(
318+
"Error: %s at %s:%d", message.data(), filename.data(), line)
319+
.c_str());
320+
}
321+
322+
static void SetLastErrorMessage(const std::vector<std::string>& message) {
323+
std::string message_str;
324+
bool first = true;
325+
for (const std::string& part : message) {
326+
if (!first) {
327+
message_str += '\n';
328+
} else {
329+
first = false;
330+
}
331+
message_str += part;
332+
}
333+
SetLastErrorMessage(message_str.c_str());
334+
}
335+
336+
static void ClearLastErrorMessage() {
337+
node_embedding_last_error_message_set(nullptr);
338+
}
339+
340+
static std::string GetAndClearLastErrorMessage() {
341+
std::string result = GetLastErrorMessage();
342+
ClearLastErrorMessage();
343+
return result;
344+
}
345+
};
346+
347+
// NodeHandleExecutionResultCallback supported signatures:
348+
// - void(const NodeRuntime& runtime,
349+
// napi_env env,
350+
// napi_value execution_result);
351+
using NodeHandleExecutionResultCallback =
352+
NodeFunctor<node_embedding_runtime_loaded_callback>;
353+
354+
// NodeInitializeModuleCallback supported signatures:
355+
// - napi_value(const NodeRuntime& runtime,
356+
// napi_env env,
357+
// std::string_view module_name,
358+
// napi_value exports);
359+
using NodeInitializeModuleCallback =
360+
NodeFunctor<node_embedding_module_initialize_callback>;
361+
362+
// NodeRunTaskCallback supported signatures:
363+
// - NodeExpected<void>();
364+
using NodeRunTaskCallback = NodeFunctor<node_embedding_task_run_callback>;
365+
366+
// NodePostTaskCallback supported signatures:
367+
// - NodeExpected<bool>(NodeRunTaskCallback run_task);
368+
using NodePostTaskCallback = NodeFunctor<node_embedding_task_post_callback>;
369+
95370
//------------------------------------------------------------------------------
96371
// Convenience functor struct adapter for C++ function object or lambdas.
97372
//------------------------------------------------------------------------------

0 commit comments

Comments
 (0)