Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modules: adding load linked modules feature #8

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,10 @@ static bool use_debug_agent = false;
static bool debug_wait_connect = false;
static int debug_port = 5858;
static bool v8_is_profiling = false;
static bool node_is_initialized = false;
static node_module* modpending;
static node_module* modlist_builtin;
static node_module* modlist_linked;
static node_module* modlist_addon;

#if defined(NODE_HAVE_I18N_SUPPORT)
Expand Down Expand Up @@ -2040,7 +2042,15 @@ 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) {
// "Linked" modules are included as part of the node project.
// Like builtins they are registered *before* node::Init runs.
mp->nm_flags = NM_F_LINKED;
mp->nm_link = modlist_linked;
modlist_linked = mp;
} else {
// Once node::Init was called we can only register dynamic modules.
// See DLOpen.
CHECK_EQ(modpending, nullptr);
modpending = mp;
}
Expand All @@ -2058,6 +2068,18 @@ struct node_module* get_builtin_module(const char* name) {
return (mp);
}

struct node_module* get_linked_module(const char* name) {
struct node_module* mp;

for (mp = modlist_linked; mp != NULL; mp = mp->nm_link) {
if (strcmp(mp->nm_modname, name) == 0)
break;
}

CHECK(mp == NULL || (mp->nm_flags & NM_F_LINKED) != 0);
return mp;
}

typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);

// DLOpen is process.dlopen(module, filename).
Expand Down Expand Up @@ -2262,6 +2284,46 @@ static void Binding(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(exports);
}

static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());

Local<String> module = args[0]->ToString();

Local<Object> cache = env->binding_cache_object();
Local<Value> exports_v = cache->Get(module);

if (exports_v->IsObject())
return args.GetReturnValue().Set(exports_v.As<Object>());

node::Utf8Value module_v(module);
node_module* mod = get_linked_module(*module_v);

if (mod == NULL) {
char errmsg[1024];
snprintf(errmsg,
sizeof(errmsg),
"No such module was linked: %s",
*module_v);
return env->ThrowError(errmsg);
}

Local<Object> exports = Object::New(env->isolate());

if (mod->nm_context_register_func != NULL) {
mod->nm_context_register_func(exports,
module,
env->context(),
mod->nm_priv);
} else if (mod->nm_register_func != NULL) {
mod->nm_register_func(exports, module, mod->nm_priv);
} else {
return env->ThrowError("Linked module has no declared entry point.");
}

cache->Set(module, exports);

args.GetReturnValue().Set(exports);
}

static void ProcessTitleGetter(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
Expand Down Expand Up @@ -2801,6 +2863,7 @@ void SetupProcessObject(Environment* env,
env->SetMethod(process, "memoryUsage", MemoryUsage);

env->SetMethod(process, "binding", Binding);
env->SetMethod(process, "_linkedBinding", LinkedBinding);

env->SetMethod(process, "_setupAsyncListener", SetupAsyncListener);
env->SetMethod(process, "_setupNextTick", SetupNextTick);
Expand Down Expand Up @@ -3700,6 +3763,7 @@ int Start(int argc, char** argv) {

int code;
V8::Initialize();
node_is_initialized = true;

// Fetch a reference to the main isolate, so we have a reference to it
// even when we need it to access it from another (debugger) thread.
Expand Down
2 changes: 2 additions & 0 deletions src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ typedef void (*addon_context_register_func)(
void* priv);

#define NM_F_BUILTIN 0x01
#define NM_F_LINKED 0x02

struct node_module {
int nm_version;
Expand All @@ -353,6 +354,7 @@ struct node_module {
};

node_module* get_builtin_module(const char *name);
node_module* get_linked_module(const char *name);

extern "C" NODE_EXTERN void node_module_register(void* mod);

Expand Down