Skip to content

Commit a13f0a6

Browse files
addaleaxtargos
authored andcommitted
src: add public API for linked bindings
(Re-?)add a public API for creating linked bindings (access to `NM_F_LINKED` as a constant was previously removed in d6ac8a4), and add a test for the functionality. PR-URL: #26457 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Shelley Vohr <codebytere@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent e531258 commit a13f0a6

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

node.gyp

+1
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,7 @@
10021002
'test/cctest/test_base64.cc',
10031003
'test/cctest/test_node_postmortem_metadata.cc',
10041004
'test/cctest/test_environment.cc',
1005+
'test/cctest/test_linked_binding.cc',
10051006
'test/cctest/test_platform.cc',
10061007
'test/cctest/test_report_util.cc',
10071008
'test/cctest/test_traced_value.cc',

src/node.h

+12
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,10 @@ typedef void (*addon_context_register_func)(
445445
v8::Local<v8::Context> context,
446446
void* priv);
447447

448+
enum ModuleFlags {
449+
kLinked = 0x02
450+
};
451+
448452
struct node_module {
449453
int nm_version;
450454
unsigned int nm_flags;
@@ -532,6 +536,14 @@ extern "C" NODE_EXTERN void node_module_register(void* mod);
532536
/* NOLINTNEXTLINE (readability/null_usage) */ \
533537
NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, 0)
534538

539+
// Embedders can use this type of binding for statically linked native bindings.
540+
// It is used the same way addon bindings are used, except that linked bindings
541+
// can be accessed through `process._linkedBinding(modname)`.
542+
#define NODE_MODULE_LINKED(modname, regfunc) \
543+
/* NOLINTNEXTLINE (readability/null_usage) */ \
544+
NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, \
545+
node::ModuleFlags::kLinked)
546+
535547
/*
536548
* For backward compatibility in add-on modules.
537549
*/

src/node_binding.h

+5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ enum {
2121
NM_F_DELETEME = 1 << 3,
2222
};
2323

24+
// Make sure our internal values match the public API's values.
25+
static_assert(static_cast<int>(NM_F_LINKED) ==
26+
static_cast<int>(node::ModuleFlags::kLinked),
27+
"NM_F_LINKED != node::ModuleFlags::kLinked");
28+
2429
#define NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, priv, flags) \
2530
static node::node_module _module = { \
2631
NODE_MODULE_VERSION, \

test/cctest/test_linked_binding.cc

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include "node_test_fixture.h"
2+
#include "node_internals.h" // RunBootstrapping()
3+
4+
void InitializeBinding(v8::Local<v8::Object> exports,
5+
v8::Local<v8::Value> module,
6+
v8::Local<v8::Context> context) {
7+
v8::Isolate* isolate = context->GetIsolate();
8+
exports->Set(
9+
context,
10+
v8::String::NewFromOneByte(isolate,
11+
reinterpret_cast<const uint8_t*>("key"),
12+
v8::NewStringType::kNormal).ToLocalChecked(),
13+
v8::String::NewFromOneByte(isolate,
14+
reinterpret_cast<const uint8_t*>("value"),
15+
v8::NewStringType::kNormal).ToLocalChecked())
16+
.FromJust();
17+
}
18+
19+
NODE_MODULE_LINKED(cctest_linkedbinding, InitializeBinding);
20+
21+
class LinkedBindingTest : public EnvironmentTestFixture {};
22+
23+
TEST_F(LinkedBindingTest, SimpleTest) {
24+
const v8::HandleScope handle_scope(isolate_);
25+
const Argv argv;
26+
Env test_env {handle_scope, argv};
27+
28+
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
29+
30+
const char* run_script =
31+
"process._linkedBinding('cctest_linkedbinding').key";
32+
v8::Local<v8::Script> script = v8::Script::Compile(
33+
context,
34+
v8::String::NewFromOneByte(isolate_,
35+
reinterpret_cast<const uint8_t*>(run_script),
36+
v8::NewStringType::kNormal).ToLocalChecked())
37+
.ToLocalChecked();
38+
v8::Local<v8::Value> completion_value = script->Run(context).ToLocalChecked();
39+
v8::String::Utf8Value utf8val(isolate_, completion_value);
40+
CHECK_NOT_NULL(*utf8val);
41+
CHECK_EQ(strcmp(*utf8val, "value"), 0);
42+
}

0 commit comments

Comments
 (0)