Skip to content

Commit

Permalink
src: add public API for linked bindings
Browse files Browse the repository at this point in the history
(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>
  • Loading branch information
addaleax authored and targos committed Mar 27, 2019
1 parent e531258 commit a13f0a6
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,7 @@
'test/cctest/test_base64.cc',
'test/cctest/test_node_postmortem_metadata.cc',
'test/cctest/test_environment.cc',
'test/cctest/test_linked_binding.cc',
'test/cctest/test_platform.cc',
'test/cctest/test_report_util.cc',
'test/cctest/test_traced_value.cc',
Expand Down
12 changes: 12 additions & 0 deletions src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,10 @@ typedef void (*addon_context_register_func)(
v8::Local<v8::Context> context,
void* priv);

enum ModuleFlags {
kLinked = 0x02
};

struct node_module {
int nm_version;
unsigned int nm_flags;
Expand Down Expand Up @@ -532,6 +536,14 @@ extern "C" NODE_EXTERN void node_module_register(void* mod);
/* NOLINTNEXTLINE (readability/null_usage) */ \
NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, 0)

// Embedders can use this type of binding for statically linked native bindings.
// It is used the same way addon bindings are used, except that linked bindings
// can be accessed through `process._linkedBinding(modname)`.
#define NODE_MODULE_LINKED(modname, regfunc) \
/* NOLINTNEXTLINE (readability/null_usage) */ \
NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, \
node::ModuleFlags::kLinked)

/*
* For backward compatibility in add-on modules.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/node_binding.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ enum {
NM_F_DELETEME = 1 << 3,
};

// Make sure our internal values match the public API's values.
static_assert(static_cast<int>(NM_F_LINKED) ==
static_cast<int>(node::ModuleFlags::kLinked),
"NM_F_LINKED != node::ModuleFlags::kLinked");

#define NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, priv, flags) \
static node::node_module _module = { \
NODE_MODULE_VERSION, \
Expand Down
42 changes: 42 additions & 0 deletions test/cctest/test_linked_binding.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "node_test_fixture.h"
#include "node_internals.h" // RunBootstrapping()

void InitializeBinding(v8::Local<v8::Object> exports,
v8::Local<v8::Value> module,
v8::Local<v8::Context> context) {
v8::Isolate* isolate = context->GetIsolate();
exports->Set(
context,
v8::String::NewFromOneByte(isolate,
reinterpret_cast<const uint8_t*>("key"),
v8::NewStringType::kNormal).ToLocalChecked(),
v8::String::NewFromOneByte(isolate,
reinterpret_cast<const uint8_t*>("value"),
v8::NewStringType::kNormal).ToLocalChecked())
.FromJust();
}

NODE_MODULE_LINKED(cctest_linkedbinding, InitializeBinding);

class LinkedBindingTest : public EnvironmentTestFixture {};

TEST_F(LinkedBindingTest, SimpleTest) {
const v8::HandleScope handle_scope(isolate_);
const Argv argv;
Env test_env {handle_scope, argv};

v8::Local<v8::Context> context = isolate_->GetCurrentContext();

const char* run_script =
"process._linkedBinding('cctest_linkedbinding').key";
v8::Local<v8::Script> script = v8::Script::Compile(
context,
v8::String::NewFromOneByte(isolate_,
reinterpret_cast<const uint8_t*>(run_script),
v8::NewStringType::kNormal).ToLocalChecked())
.ToLocalChecked();
v8::Local<v8::Value> completion_value = script->Run(context).ToLocalChecked();
v8::String::Utf8Value utf8val(isolate_, completion_value);
CHECK_NOT_NULL(*utf8val);
CHECK_EQ(strcmp(*utf8val, "value"), 0);
}

0 comments on commit a13f0a6

Please sign in to comment.