Skip to content
Browse files

Register builtin extensions via a macro, rather than a manual strcmp

Set the stage for making the builtin modules more dynamic.

Note: this only converts crypto and net, I will add more extensions in a
later commit.

* node.h: Add utility macro for converting macro values to strings.

* node.h: Include the actual module name inside the module structure, not
  just the file it was built from.

* node.h: New Macro, NODE_MODULE_DECL, for declaring an external reference
  to a module structure.

* node_extensions.cc: New File, implements get_builtin_module, which
  iterates over the module structures that are compiled into node.

* node.cc(node::Binding): Use the new module lookup function to find
  modules.

* node_{net,crypto}.c: Add NODE_MODULEs to generate the module structure.
  • Loading branch information...
1 parent 781d512 commit 30dadfc033b45842691cef02caf059ba5db0b63a @pquerna pquerna committed with ry Jul 13, 2010
Showing with 83 additions and 27 deletions.
  1. +10 −22 src/node.cc
  2. +14 −3 src/node.h
  3. +2 −2 src/node_crypto.cc
  4. +46 −0 src/node_extensions.cc
  5. +8 −0 src/node_extensions.h
  6. +2 −0 src/node_net.cc
  7. +1 −0 wscript
View
32 src/node.cc
@@ -1571,16 +1571,23 @@ static Handle<Value> Binding(const Arguments& args) {
Local<String> module = args[0]->ToString();
String::Utf8Value module_v(module);
+ node_module_struct* modp;
if (binding_cache.IsEmpty()) {
binding_cache = Persistent<Object>::New(Object::New());
}
Local<Object> exports;
- // TODO DRY THIS UP!
-
- if (!strcmp(*module_v, "stdio")) {
+ if (binding_cache->Has(module)) {
+ exports = binding_cache->Get(module)->ToObject();
+ }
+ else if ((modp = get_builtin_module(*module_v)) != NULL) {
+ exports = Object::New();
+ modp->register_func(exports);
+ binding_cache->Set(module, exports);
+ }
+ else if (!strcmp(*module_v, "stdio")) {
if (binding_cache->Has(module)) {
exports = binding_cache->Get(module)->ToObject();
} else {
@@ -1623,15 +1630,6 @@ static Handle<Value> Binding(const Arguments& args) {
binding_cache->Set(module, exports);
}
- } else if (!strcmp(*module_v, "net")) {
- if (binding_cache->Has(module)) {
- exports = binding_cache->Get(module)->ToObject();
- } else {
- exports = Object::New();
- InitNet(exports);
- binding_cache->Set(module, exports);
- }
-
} else if (!strcmp(*module_v, "http_parser")) {
if (binding_cache->Has(module)) {
exports = binding_cache->Get(module)->ToObject();
@@ -1658,16 +1656,6 @@ static Handle<Value> Binding(const Arguments& args) {
Buffer::Initialize(exports);
binding_cache->Set(module, exports);
}
- #ifdef HAVE_OPENSSL
- } else if (!strcmp(*module_v, "crypto")) {
- if (binding_cache->Has(module)) {
- exports = binding_cache->Get(module)->ToObject();
- } else {
- exports = Object::New();
- InitCrypto(exports);
- binding_cache->Set(module, exports);
- }
- #endif
} else if (!strcmp(*module_v, "evals")) {
if (binding_cache->Has(module)) {
exports = binding_cache->Get(module)->ToObject();
View
17 src/node.h
@@ -10,6 +10,11 @@
#include <node_object_wrap.h>
+#ifndef NODE_STRINGIFY
+#define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)
+#define NODE_STRINGIFY_HELPER(n) #n
+#endif
+
namespace node {
#define NODE_PSYMBOL(s) Persistent<String>::New(String::NewSymbol(s))
@@ -83,14 +88,16 @@ v8::Local<v8::Value> ErrnoException(int errorno,
const char *signo_string(int errorno);
-
struct node_module_struct {
int version;
void *dso_handle;
- const char *name;
+ const char *filename;
void (*register_func) (v8::Handle<v8::Object> target);
+ const char *modname;
};
+node_module_struct* get_builtin_module(const char *name);
+
/**
* When this version number is changed, node.js will refuse
* to load older modules. This should be done whenever
@@ -108,9 +115,13 @@ struct node_module_struct {
node::node_module_struct modname ## _module = \
{ \
NODE_STANDARD_MODULE_STUFF, \
- regfunc \
+ regfunc, \
+ NODE_STRINGIFY(modname) \
};
+#define NODE_MODULE_DECL(modname) \
+ extern node::node_module_struct modname ## _module;
+
} // namespace node
#endif // SRC_NODE_H_
View
4 src/node_crypto.cc
@@ -2264,7 +2264,7 @@ void InitCrypto(Handle<Object> target) {
version_symbol = NODE_PSYMBOL("version");
}
-
-
} // namespace node
+NODE_MODULE(node_crypto, node::InitCrypto);
+
View
46 src/node_extensions.cc
@@ -0,0 +1,46 @@
+
+#include "node.h"
+#include "node_version.h"
+#include <string.h>
+
+#undef NODE_EXT_LIST_START
+#undef NODE_EXT_LIST_ITEM
+#undef NODE_EXT_LIST_END
+
+#define NODE_EXT_LIST_START
+#define NODE_EXT_LIST_ITEM NODE_MODULE_DECL
+#define NODE_EXT_LIST_END
+
+#include "node_extensions.h"
+
+#undef NODE_EXT_LIST_START
+#undef NODE_EXT_LIST_ITEM
+#undef NODE_EXT_LIST_END
+
+#define NODE_EXT_STRING(x) &x ## _module,
+#define NODE_EXT_LIST_START node::node_module_struct *node_module_list[] = {
+#define NODE_EXT_LIST_ITEM NODE_EXT_STRING
+#define NODE_EXT_LIST_END NULL};
+
+#include "node_extensions.h"
+
+namespace node {
+
+node_module_struct* get_builtin_module(const char *name)
+{
+ char buf[128];
+ node_module_struct *cur = NULL;
+ snprintf(buf, sizeof(buf), "node_%s", name);
+ /* TODO: you could look these up in a hash, but there are only
+ * a few, and once loaded they are cached. */
+ for (int i = 0; node_module_list[i] != NULL; i++) {
+ cur = node_module_list[i];
+ if (strcmp(cur->modname, buf) == 0) {
+ return cur;
+ }
+ }
+
+ return NULL;
+}
+
+}; // namespace node
View
8 src/node_extensions.h
@@ -0,0 +1,8 @@
+
+NODE_EXT_LIST_START
+NODE_EXT_LIST_ITEM(node_net)
+#ifdef HAVE_OPENSSL
+NODE_EXT_LIST_ITEM(node_crypto)
+#endif
+NODE_EXT_LIST_END
+
View
2 src/node_net.cc
@@ -1266,3 +1266,5 @@ void InitNet(Handle<Object> target) {
}
} // namespace node
+
+NODE_MODULE(node_net, node::InitNet);
View
1 wscript
@@ -459,6 +459,7 @@ def build(bld):
node.source = """
src/node.cc
src/node_buffer.cc
+ src/node_extensions.cc
src/node_http_parser.cc
src/node_net.cc
src/node_io_watcher.cc

0 comments on commit 30dadfc

Please sign in to comment.
Something went wrong with that request. Please try again.