Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Modules: adding load linked modules feature #8386

Closed
wants to merge 1 commit into from
Closed

Modules: adding load linked modules feature #8386

wants to merge 1 commit into from

Conversation

thlorenz
Copy link

This PR is mainly to get some guidance if I'm on the right track (i.e. what @tjfontaine had in mind).
It enables to include C++ modules simply by adding them to the node.gyp file and loading them from JS via process.linkedBinding.

It is based on v0.12, but I can rebase on master if that is better.
Please lmk what else needs to be done to get this completed, i.e do we need tests (a little hard to do since it needs to rebuild node to run) and/or an example of how this is used?

  • introduced NM_F_LINKED flag to identify linked modules
  • setting node_is_initialized after calling V8::Initialize in order to
    make the right decision during initial module registration
  • introduced modlist_linked in order to track modules that were
    pre-registered in order to complete it once node is initialized
  • completing registration of linked module similarly to the way it's
    done inside DLOpen

Example

Assuming src/simple.cc registers itself via:

void init_simple(v8::Handle<v8::Object> exports) {
  NODE_SET_METHOD(exports, "simple", Simple);
}

NODE_MODULE(simple, init_simple)
node.gyp addition

This addition can be done manually or via nad which injects parameters derived from the existing binding.gyp into node.gyp via a simple command.

{
"conditions": [
        [
          "simple_addon==\"true\"",
          {
            "sources": [
              "addons/simple/src/simple.cc",
            ],
         }
    ]
  ]
}

Loading inside simple.js

var binding = process._linkedBinding('simple');

@thlorenz thlorenz changed the title first working version of linked modules Modules: adding load linked modules feature Sep 17, 2014
if (cache->Has(module)) {
exports = cache->Get(module)->ToObject();
args.GetReturnValue().Set(exports);
return;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead do the following:

exports = cache->Get(module).As<Object>();
if (cache->IsObject())
  return args.GetReturnValue().Set(exports);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got these snippets from somewhere else in node.cc actually. Is the above new for what's currently in master?
I was gonna remove this duplication once I got the go ahead on the general approach.

So most of this comes from Binding(). Should we change the code there as well and/or consolidate into a reusable function to avoid duplication?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a different way of accomplishing the same thing. Don't bother changing the code anywhere that isn't directly involved with your code changes.

@trevnorris
Copy link

Left a couple style comments.

To make sure I understand correctly, this is a feature that allows injecting code directly into the Node build?

@thlorenz
Copy link
Author

Yes, all you'd need to change is node.gyp file and rebuild. Then you could work on whatever you are doing as part of the node build, especially useful for addon development.

Wanted to point out again that this is based on v0.12 branch. Is that correct or do I need to rebase on something else?

@trevnorris
Copy link

Well, since master is behind v0.12, and we're just going to merge v0.12 into master once it's released just keep it as-is. Whether this is merged into v0.12 I'll leave open.

/cc @tjfontaine @indutny

@thlorenz
Copy link
Author

@trevnorris I updated this PR to match the style you indicated and tested (manually) that the feature still works the same way.

Do we need to add an example or some way to at least manually test this feature somewhere?
I would't mind adding an integration test that involves adapting the node.gyp file and rebuilding. Obviously that would be an isolated test that is run separately, i.e. not part of the tests that run on every build.

@trevnorris
Copy link

ping @indutny @tjfontaine What are your thoughts on this patch?

@@ -2030,6 +2032,10 @@ extern "C" void node_module_register(void* m) {
if (mp->nm_flags & NM_F_BUILTIN) {
mp->nm_link = modlist_builtin;
modlist_builtin = mp;
} else if (!node_is_initialized){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space between ) and {

@indutny
Copy link
Member

indutny commented Sep 23, 2014

One nit, otherwise LGTM. Let's land it in v0.12

@thlorenz
Copy link
Author

@indutny fixed the nit, waiting for @tjfontaine to reply to #8386 (comment).
The way it is currently will work, but if my approach is very different from what was intended I may have to redo it, we'll see.

@thlorenz
Copy link
Author

thlorenz commented Nov 5, 2014

Just as a note, I hid the linkedBinding function behind a _ for now to make it more feasible to merge this now even if we have to change the API later.

- introduced NM_F_LINKED flag to identify linked modules
- setting node_is_initialized after calling V8::Initialize in order to
  make the right decision during initial module registration
- introduced modlist_linked in order to track modules that were
  pre-registered in order to complete it once node is initialized
- completing registration of linked module similarly to the way it's
  done inside DLOpen
trevnorris pushed a commit that referenced this pull request Dec 1, 2014
- introduced NM_F_LINKED flag to identify linked modules
- setting node_is_initialized after calling V8::Initialize in order to
  make the right decision during initial module registration
- introduced modlist_linked in order to track modules that were
  pre-registered in order to complete it once node is initialized
- completing registration of linked module similarly to the way it's
  done inside DLOpen

PR-URL: #8386
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
@trevnorris
Copy link

Since the API is "hidden" going ahead and merging it. We can work out the details with usage and make it public in the future. Landed in c131c1f.

@trevnorris trevnorris closed this Dec 1, 2014
@thlorenz thlorenz deleted the v0.12-linked-module-loading branch December 8, 2014 21:32
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants