Move the module loading framework into lib/module.js. Minimal changes otherwise.
authorisaacs <i@izs.me>
Wed, 21 Apr 2010 01:22:51 +0000 (18:22 -0700)
committerRyan Dahl <ry@tinyclouds.org>
Wed, 21 Apr 2010 19:05:01 +0000 (12:05 -0700)
lib/module.js [new file with mode: 0644]
src/node.cc
src/node.js

diff --git a/lib/module.js b/lib/module.js
new file mode 100644 (file)
index 0000000..02df2d6
--- /dev/null
@@ -0,0 +1,466 @@
+/**********************************************************************/
+
+// Module
+
+var internalModuleCache = {};
+var extensionCache = {};
+
+function Module (id, parent) {
+  this.id = id;
+  this.exports = {};
+  this.parent = parent;
+
+  if (parent) {
+    this.moduleCache = parent.moduleCache;
+  } else {
+    this.moduleCache = {};
+  }
+  this.moduleCache[this.id] = this;
+
+  this.filename = null;
+  this.loaded = false;
+  this.exited = false;
+  this.children = [];
+};
+
+function createInternalModule (id, constructor) {
+  var m = new Module(id);
+  constructor(m.exports);
+  m.loaded = true;
+  internalModuleCache[id] = m;
+  return m;
+};
+
+
+// This contains the source code for the files in lib/
+// Like, natives.fs is the contents of lib/fs.js
+var natives = process.binding('natives');
+
+function loadNative (id) {
+  var m = new Module(id);
+  internalModuleCache[id] = m;
+  var e = m._compile(natives[id], id);
+  if (e) throw e;
+  m.loaded = true;
+  return m;
+}
+exports.requireNative = requireNative;
+function requireNative (id) {
+  if (internalModuleCache[id]) return internalModuleCache[id].exports;
+  if (!natives[id]) throw new Error('No such native module ' + id);
+  return loadNative(id).exports;
+}
+
+
+
+// Event
+
+var eventsFn = process.compile("(function (exports) {" + natives.events + "\n})",
+                               "events");
+var eventsModule = createInternalModule('events', eventsFn);
+var events = eventsModule.exports;
+
+
+// Modules
+
+var debugLevel = parseInt(process.env["NODE_DEBUG"]);
+function debug (x) {
+  if (debugLevel > 0) {
+    process.binding('stdio').writeError(x + "\n");
+  }
+}
+
+var pathFn = process.compile("(function (exports) {" + natives.path + "\n})",
+                             "path");
+var pathModule = createInternalModule('path', pathFn);
+var path = pathModule.exports;
+
+function existsSync (path) {
+  try {
+    process.binding('fs').stat(path);
+    return true;
+  } catch (e) {
+    return false;
+  }
+}
+
+
+
+var modulePaths = [];
+
+if (process.env["HOME"]) {
+  modulePaths.unshift(path.join(process.env["HOME"], ".node_libraries"));
+}
+
+if (process.env["NODE_PATH"]) {
+  modulePaths = process.env["NODE_PATH"].split(":").concat(modulePaths);
+}
+
+
+/* Sync unless callback given */
+function findModulePath (id, dirs, callback) {
+  process.assert(dirs.constructor == Array);
+
+  if (/^https?:\/\//.exec(id)) {
+    if (callback) {
+      callback(id);
+    } else {
+      throw new Error("Sync http require not allowed.");
+    }
+    return;
+  }
+
+  if (/\.(js|node)$/.exec(id)) {
+    throw new Error("No longer accepting filename extension in module names");
+  }
+
+  if (dirs.length == 0) {
+    if (callback) {
+      callback();
+    } else {
+      return; // sync returns null
+    }
+  }
+
+  var dir = dirs[0];
+  var rest = dirs.slice(1, dirs.length);
+
+  if (id.charAt(0) == '/') {
+    dir = '';
+    rest = [];
+  }
+
+  var locations = [
+    path.join(dir, id + ".js"),
+    path.join(dir, id + ".node"),
+    path.join(dir, id, "index.js"),
+    path.join(dir, id, "index.node")
+  ];
+
+  var ext;
+  var extensions = Object.keys(extensionCache);
+  for (var i = 0, l = extensions.length; i < l; i++) {
+    var ext = extensions[i];
+    locations.push(path.join(dir, id + ext));
+    locations.push(path.join(dir, id, 'index' + ext));
+  }
+
+  function searchLocations () {
+    var location = locations.shift();
+    if (!location) {
+      return findModulePath(id, rest, callback);
+    }
+
+    // if async
+    if (callback) {
+      path.exists(location, function (found) {
+        if (found) {
+          callback(location);
+        } else {
+          return searchLocations();
+        }
+      });
+
+    // if sync
+    } else {
+      if (existsSync(location)) {
+        return location;
+      } else {
+        return searchLocations();
+      }
+    }
+  }
+  return searchLocations();
+}
+
+
+// sync - no i/o performed
+function resolveModulePath(request, parent) {
+  var id, paths;
+  if (request.charAt(0) == "." && (request.charAt(1) == "/" || request.charAt(1) == ".")) {
+    // Relative request
+    debug("RELATIVE: requested:" + request + " set ID to: "+id+" from "+parent.id);
+
+    var exts = ['js', 'node'], ext;
+    var extensions = Object.keys(extensionCache);
+    for (var i = 0, l = extensions.length; i < l; i++) {
+      var ext = extensions[i];
+      exts.push(ext.slice(1));
+    }
+
+    var parentIdPath = path.dirname(parent.id +
+      (path.basename(parent.filename).match(new RegExp('^index\\.(' + exts.join('|') + ')$')) ? "/" : ""));
+    id = path.join(parentIdPath, request);
+    paths = [path.dirname(parent.filename)];
+  } else {
+    id = request;
+    // debug("ABSOLUTE: id="+id);
+    paths = modulePaths;
+  }
+
+  return [id, paths];
+}
+
+
+function loadModule (request, parent, callback) {
+  var resolvedModule = resolveModulePath(request, parent),
+      id = resolvedModule[0],
+      paths = resolvedModule[1];
+
+  debug("loadModule REQUEST  " + (request) + " parent: " + parent.id);
+
+  var cachedModule = internalModuleCache[id] || parent.moduleCache[id];
+
+  if (!cachedModule) {
+    // Try to compile from native modules
+    if (natives[id]) {
+      debug('load native module ' + id);
+      cachedModule = loadNative(id);
+    }
+  }
+
+  if (cachedModule) {
+    debug("found  " + JSON.stringify(id) + " in cache");
+    if (callback) {
+      callback(null, cachedModule.exports);
+    } else {
+      return cachedModule.exports;
+    }
+
+  } else {
+    // Not in cache
+    debug("looking for " + JSON.stringify(id) + " in " + JSON.stringify(paths));
+
+    if (!callback) {
+      // sync
+      var filename = findModulePath(request, paths);
+      if (!filename) {
+        throw new Error("Cannot find module '" + request + "'");
+      } else {
+        var module = new Module(id, parent);
+        module.loadSync(filename);
+        return module.exports;
+      }
+
+    } else {
+      // async
+      findModulePath(request, paths, function (filename) {
+        if (!filename) {
+          var err = new Error("Cannot find module '" + request + "'");
+          callback(err);
+        } else {
+          var module = new Module(id, parent);
+          module.load(filename, callback);
+        }
+      });
+    }
+  }
+};
+
+
+// This function allows the user to register file extensions to custom
+// Javascript 'compilers'.  It accepts 2 arguments, where ext is a file
+// extension as a string. E.g. '.coffee' for coffee-script files.  compiler
+// is the second argument, which is a function that gets called when the
+// specified file extension is found. The compiler is passed a single
+// argument, which is, the file contents, which need to be compiled.
+//
+// The function needs to return the compiled source, or an non-string
+// variable that will get attached directly to the module exports. Example:
+//
+//    require.registerExtension('.coffee', function(content) {
+//      return doCompileMagic(content);
+//    });
+function registerExtension(ext, compiler) {
+  if ('string' !== typeof ext && false === /\.\w+$/.test(ext)) {
+    throw new Error('require.registerExtension: First argument not a valid extension string.');
+  }
+
+  if ('function' !== typeof compiler) {
+    throw new Error('require.registerExtension: Second argument not a valid compiler function.');
+  }
+
+  extensionCache[ext] = compiler;
+}
+
+
+Module.prototype.loadSync = function (filename) {
+  debug("loadSync " + JSON.stringify(filename) + " for module " + JSON.stringify(this.id));
+
+  process.assert(!this.loaded);
+  this.filename = filename;
+
+  if (filename.match(/\.node$/)) {
+    this._loadObjectSync(filename);
+  } else {
+    this._loadScriptSync(filename);
+  }
+};
+
+
+Module.prototype.load = function (filename, callback) {
+  debug("load " + JSON.stringify(filename) + " for module " + JSON.stringify(this.id));
+
+  process.assert(!this.loaded);
+
+  this.filename = filename;
+
+  if (filename.match(/\.node$/)) {
+    this._loadObject(filename, callback);
+  } else {
+    this._loadScript(filename, callback);
+  }
+};
+
+
+Module.prototype._loadObjectSync = function (filename) {
+  this.loaded = true;
+  process.dlopen(filename, this.exports);
+};
+
+
+Module.prototype._loadObject = function (filename, callback) {
+  var self = this;
+  // XXX Not yet supporting loading from HTTP. would need to download the
+  // file, store it to tmp then run dlopen on it.
+  self.loaded = true;
+  process.dlopen(filename, self.exports); // FIXME synchronus
+  if (callback) callback(null, self.exports);
+};
+
+
+function cat (id, callback) {
+  if (id.match(/^http:\/\//)) {
+    loadModule('http', process.mainModule, function (err, http) {
+      if (err) {
+        if (callback) callback(err);
+      } else {
+        http.cat(id, callback);
+      }
+    });
+  } else {
+    requireNative('fs').readFile(id, callback);
+  }
+}
+
+
+// Returns exception if any
+Module.prototype._compile = function (content, filename) {
+  var self = this;
+  // remove shebang
+  content = content.replace(/^\#\!.*/, '');
+
+  // Compile content if needed
+  var ext = path.extname(filename);
+  if (extensionCache[ext]) {
+    content = extensionCache[ext](content);
+  }
+
+  function requireAsync (url, cb) {
+    loadModule(url, self, cb);
+  }
+
+  function require (path) {
+    return loadModule(path, self);
+  }
+
+  require.paths = modulePaths;
+  require.async = requireAsync;
+  require.main = process.mainModule;
+  require.registerExtension = registerExtension;
+
+
+  if ('string' === typeof content) {
+    // create wrapper function
+    var wrapper = "(function (exports, require, module, __filename, __dirname) { "
+                + content
+                + "\n});";
+
+    try {
+      var compiledWrapper = process.compile(wrapper, filename);
+      var dirName = path.dirname(filename);
+      if (filename === process.argv[1]) {
+        process.checkBreak();
+      }
+      compiledWrapper.apply(self.exports, [self.exports, require, self, filename, dirName]);
+    } catch (e) {
+      return e;
+    }
+  } else {
+    self.exports = content;
+  }
+};
+
+
+Module.prototype._loadScriptSync = function (filename) {
+  var content = requireNative('fs').readFileSync(filename);
+  var e = this._compile(content, filename);
+  if (e) {
+    throw e;
+  } else {
+    this.loaded = true;
+  }
+};
+
+
+Module.prototype._loadScript = function (filename, callback) {
+  var self = this;
+  cat(filename, function (err, content) {
+    debug('cat done');
+    if (err) {
+      if (callback) callback(err);
+    } else {
+      var e = self._compile(content, filename);
+      if (e) {
+        if (callback) callback(e);
+      } else {
+        self._waitChildrenLoad(function () {
+          self.loaded = true;
+          if (self.onload) self.onload();
+          if (callback) callback(null, self.exports);
+        });
+      }
+    }
+  });
+};
+
+
+Module.prototype._waitChildrenLoad = function (callback) {
+  var nloaded = 0;
+  var children = this.children;
+  for (var i = 0; i < children.length; i++) {
+    var child = children[i];
+    if (child.loaded) {
+      nloaded++;
+    } else {
+      child.onload = function () {
+        child.onload = null;
+        nloaded++;
+        if (children.length == nloaded && callback) callback();
+      };
+    }
+  }
+  if (children.length == nloaded && callback) callback();
+};
+
+
+
+// bootstrap main module.
+exports.runMain = function () {
+  var cwd = process.cwd();
+
+  // Make process.argv[0] and process.argv[1] into full paths.
+  if (process.argv[0].indexOf('/') > 0) {
+    process.argv[0] = path.join(cwd, process.argv[0]);
+  }
+
+  if (process.argv[1].charAt(0) != "/" && !(/^http:\/\//).exec(process.argv[1])) {
+    process.argv[1] = path.join(cwd, process.argv[1]);
+  }
+
+  // Load the main module--the command line argument.
+  process.mainModule = new Module(".");
+  process.mainModule.load(process.argv[1], function (err) {
+    if (err) throw err;
+  });
+}
index 9daf50c..e8d6c8e 100644 (file)
@@ -1307,8 +1307,8 @@ static Handle<Value> Binding(const Arguments& args) {
       exports->Set(String::New("uri"),          String::New(native_uri));
       exports->Set(String::New("url"),          String::New(native_url));
       exports->Set(String::New("utils"),        String::New(native_utils));
-      exports->Set(String::New("events"),       String::New(native_events));
       exports->Set(String::New("path"),         String::New(native_path));
+      exports->Set(String::New("module"),       String::New(native_module));
       binding_cache->Set(module, exports);
     }
 
index f2b4854..7c5af33 100644 (file)
@@ -42,59 +42,6 @@ node.tcp.createConnection = removed("node.tcp.createConnection() has moved. Use
 node.dns = {};
 node.dns.createConnection = removed("node.dns.createConnection() has moved. Use require('dns') to access it.");
 
-/**********************************************************************/
-
-// Module
-
-var internalModuleCache = {};
-var extensionCache = {};
-
-function Module (id, parent) {
-  this.id = id;
-  this.exports = {};
-  this.parent = parent;
-
-  if (parent) {
-    this.moduleCache = parent.moduleCache;
-  } else {
-    this.moduleCache = {};
-  }
-  this.moduleCache[this.id] = this;
-
-  this.filename = null;
-  this.loaded = false;
-  this.exited = false;
-  this.children = [];
-};
-
-function createInternalModule (id, constructor) {
-  var m = new Module(id);
-  constructor(m.exports);
-  m.loaded = true;
-  internalModuleCache[id] = m;
-  return m;
-};
-
-
-// This contains the source code for the files in lib/
-// Like, natives.fs is the contents of lib/fs.js
-var natives = process.binding('natives');
-
-function loadNative (id) {
-  var m = new Module(id);
-  internalModuleCache[id] = m;
-  var e = m._compile(natives[id], id);
-  if (e) throw e;
-  m.loaded = true;
-  return m;
-}
-
-function requireNative (id) {
-  if (internalModuleCache[id]) return internalModuleCache[id].exports;
-  if (!natives[id]) throw new Error('No such native module ' + id);
-  return loadNative(id).exports;
-}
-
 
 process.assert = function (x, msg) {
   if (!(x)) throw new Error(msg || "assertion error");
@@ -102,16 +49,6 @@ process.assert = function (x, msg) {
 
 process.evalcx = process.binding('evals').Script.runInNewContext;
 
-// Event
-var eventsModule = createInternalModule
-  ( 'events'
-  , process.compile
-    ( "(function (exports) {" + natives.events + "})"
-    , "events"
-    )
-  );
-var events = eventsModule.exports;
-
 // nextTick()
 
 var nextTickQueue = [];
@@ -129,9 +66,15 @@ process.nextTick = function (callback) {
   process._needTickCallback();
 };
 
+// Module System
+var module = {}
+process.compile("(function (exports) {"
+               + process.binding("natives").module
+               + "\n})", "module")(module);
 
-
-
+// TODO: make sure that event module gets loaded here once it's
+// factored out of module.js
+// module.require("events");
 
 // Signal Handlers
 
@@ -149,7 +92,6 @@ process.addListener("newListener", function (event) {
   }
 });
 
-
 // Timers
 function addTimerListener (callback) {
   var timer = this;
@@ -184,401 +126,10 @@ global.clearTimeout = function (timer) {
 
 global.clearInterval = global.clearTimeout;
 
-
-
-
-// Modules
-
-var debugLevel = parseInt(process.env["NODE_DEBUG"]);
-function debug (x) {
-  if (debugLevel > 0) {
-    process.binding('stdio').writeError(x + "\n");
-  }
-}
-
-var pathModule = createInternalModule
-  ( 'path'
-  , process.compile
-    ( "(function (exports) {" + natives.path + "})"
-    , "path"
-    )
-  );
-
-var path = pathModule.exports;
-
-function existsSync (path) {
-  try {
-    process.binding('fs').stat(path);
-    return true;
-  } catch (e) {
-    return false;
-  }
-}
-
-
-
-var modulePaths = [];
-
-if (process.env["HOME"]) {
-  modulePaths.unshift(path.join(process.env["HOME"], ".node_libraries"));
-}
-
-if (process.env["NODE_PATH"]) {
-  modulePaths = process.env["NODE_PATH"].split(":").concat(modulePaths);
-}
-
-
-/* Sync unless callback given */
-function findModulePath (id, dirs, callback) {
-  process.assert(dirs.constructor == Array);
-
-  if (/^https?:\/\//.exec(id)) {
-    if (callback) {
-      callback(id);
-    } else {
-      throw new Error("Sync http require not allowed.");
-    }
-    return;
-  }
-
-  if (/\.(js|node)$/.exec(id)) {
-    throw new Error("No longer accepting filename extension in module names");
-  }
-
-  if (dirs.length == 0) {
-    if (callback) {
-      callback();
-    } else {
-      return; // sync returns null
-    }
-  }
-
-  var dir = dirs[0];
-  var rest = dirs.slice(1, dirs.length);
-
-  if (id.charAt(0) == '/') {
-    dir = '';
-    rest = [];
-  }
-
-  var locations = [
-    path.join(dir, id + ".js"),
-    path.join(dir, id + ".node"),
-    path.join(dir, id, "index.js"),
-    path.join(dir, id, "index.node")
-  ];
-
-  var ext;
-  var extensions = Object.keys(extensionCache);
-  for (var i = 0, l = extensions.length; i < l; i++) {
-    var ext = extensions[i];
-    locations.push(path.join(dir, id + ext));
-    locations.push(path.join(dir, id, 'index' + ext));
-  }
-
-  function searchLocations () {
-    var location = locations.shift();
-    if (!location) {
-      return findModulePath(id, rest, callback);
-    }
-
-    // if async
-    if (callback) {
-      path.exists(location, function (found) {
-        if (found) {
-          callback(location);
-        } else {
-          return searchLocations();
-        }
-      });
-
-    // if sync
-    } else {
-      if (existsSync(location)) {
-        return location;
-      } else {
-        return searchLocations();
-      }
-    }
-  }
-  return searchLocations();
-}
-
-
-// sync - no i/o performed
-function resolveModulePath(request, parent) {
-  var id, paths;
-  if (request.charAt(0) == "." && (request.charAt(1) == "/" || request.charAt(1) == ".")) {
-    // Relative request
-    debug("RELATIVE: requested:" + request + " set ID to: "+id+" from "+parent.id);
-
-    var exts = ['js', 'node'], ext;
-    var extensions = Object.keys(extensionCache);
-    for (var i = 0, l = extensions.length; i < l; i++) {
-      var ext = extensions[i];
-      exts.push(ext.slice(1));
-    }
-
-    var parentIdPath = path.dirname(parent.id +
-      (path.basename(parent.filename).match(new RegExp('^index\\.(' + exts.join('|') + ')$')) ? "/" : ""));
-    id = path.join(parentIdPath, request);
-    paths = [path.dirname(parent.filename)];
-  } else {
-    id = request;
-    // debug("ABSOLUTE: id="+id);
-    paths = modulePaths;
-  }
-
-  return [id, paths];
-}
-
-
-function loadModule (request, parent, callback) {
-  var resolvedModule = resolveModulePath(request, parent),
-      id = resolvedModule[0],
-      paths = resolvedModule[1];
-
-  debug("loadModule REQUEST  " + (request) + " parent: " + parent.id);
-
-  var cachedModule = internalModuleCache[id] || parent.moduleCache[id];
-
-  if (!cachedModule) {
-    // Try to compile from native modules
-    if (natives[id]) {
-      debug('load native module ' + id);
-      cachedModule = loadNative(id);
-    }
-  }
-
-  if (cachedModule) {
-    debug("found  " + JSON.stringify(id) + " in cache");
-    if (callback) {
-      callback(null, cachedModule.exports);
-    } else {
-      return cachedModule.exports;
-    }
-
-  } else {
-    // Not in cache
-    debug("looking for " + JSON.stringify(id) + " in " + JSON.stringify(paths));
-
-    if (!callback) {
-      // sync
-      var filename = findModulePath(request, paths);
-      if (!filename) {
-        throw new Error("Cannot find module '" + request + "'");
-      } else {
-        var module = new Module(id, parent);
-        module.loadSync(filename);
-        return module.exports;
-      }
-
-    } else {
-      // async
-      findModulePath(request, paths, function (filename) {
-        if (!filename) {
-          var err = new Error("Cannot find module '" + request + "'");
-          callback(err);
-        } else {
-          var module = new Module(id, parent);
-          module.load(filename, callback);
-        }
-      });
-    }
-  }
-};
-
-
-// This function allows the user to register file extensions to custom
-// Javascript 'compilers'.  It accepts 2 arguments, where ext is a file
-// extension as a string. E.g. '.coffee' for coffee-script files.  compiler
-// is the second argument, which is a function that gets called when the
-// specified file extension is found. The compiler is passed a single
-// argument, which is, the file contents, which need to be compiled.
-//
-// The function needs to return the compiled source, or an non-string
-// variable that will get attached directly to the module exports. Example:
-//
-//    require.registerExtension('.coffee', function(content) {
-//      return doCompileMagic(content);
-//    });
-function registerExtension(ext, compiler) {
-  if ('string' !== typeof ext && false === /\.\w+$/.test(ext)) {
-    throw new Error('require.registerExtension: First argument not a valid extension string.');
-  }
-
-  if ('function' !== typeof compiler) {
-    throw new Error('require.registerExtension: Second argument not a valid compiler function.');
-  }
-
-  extensionCache[ext] = compiler;
-}
-
-
-Module.prototype.loadSync = function (filename) {
-  debug("loadSync " + JSON.stringify(filename) + " for module " + JSON.stringify(this.id));
-
-  process.assert(!this.loaded);
-  this.filename = filename;
-
-  if (filename.match(/\.node$/)) {
-    this._loadObjectSync(filename);
-  } else {
-    this._loadScriptSync(filename);
-  }
-};
-
-
-Module.prototype.load = function (filename, callback) {
-  debug("load " + JSON.stringify(filename) + " for module " + JSON.stringify(this.id));
-
-  process.assert(!this.loaded);
-
-  this.filename = filename;
-
-  if (filename.match(/\.node$/)) {
-    this._loadObject(filename, callback);
-  } else {
-    this._loadScript(filename, callback);
-  }
-};
-
-
-Module.prototype._loadObjectSync = function (filename) {
-  this.loaded = true;
-  process.dlopen(filename, this.exports);
-};
-
-
-Module.prototype._loadObject = function (filename, callback) {
-  var self = this;
-  // XXX Not yet supporting loading from HTTP. would need to download the
-  // file, store it to tmp then run dlopen on it.
-  self.loaded = true;
-  process.dlopen(filename, self.exports); // FIXME synchronus
-  if (callback) callback(null, self.exports);
-};
-
-
-function cat (id, callback) {
-  if (id.match(/^http:\/\//)) {
-    loadModule('http', process.mainModule, function (err, http) {
-      if (err) {
-        if (callback) callback(err);
-      } else {
-        http.cat(id, callback);
-      }
-    });
-  } else {
-    requireNative('fs').readFile(id, callback);
-  }
-}
-
-
-// Returns exception if any
-Module.prototype._compile = function (content, filename) {
-  var self = this;
-  // remove shebang
-  content = content.replace(/^\#\!.*/, '');
-
-  // Compile content if needed
-  var ext = path.extname(filename);
-  if (extensionCache[ext]) {
-    content = extensionCache[ext](content);
-  }
-
-  function requireAsync (url, cb) {
-    loadModule(url, self, cb);
-  }
-
-  function require (path) {
-    return loadModule(path, self);
-  }
-
-  require.paths = modulePaths;
-  require.async = requireAsync;
-  require.main = process.mainModule;
-  require.registerExtension = registerExtension;
-
-
-  if ('string' === typeof content) {
-    // create wrapper function
-    var wrapper = "(function (exports, require, module, __filename, __dirname) { "
-                + content
-                + "\n});";
-
-    try {
-      var compiledWrapper = process.compile(wrapper, filename);
-      var dirName = path.dirname(filename);
-      if (filename === process.argv[1]) {
-        process.checkBreak();
-      }
-      compiledWrapper.apply(self.exports, [self.exports, require, self, filename, dirName]);
-    } catch (e) {
-      return e;
-    }
-  } else {
-    self.exports = content;
-  }
-};
-
-
-Module.prototype._loadScriptSync = function (filename) {
-  var content = requireNative('fs').readFileSync(filename);
-  var e = this._compile(content, filename);
-  if (e) {
-    throw e;
-  } else {
-    this.loaded = true;
-  }
-};
-
-
-Module.prototype._loadScript = function (filename, callback) {
-  var self = this;
-  cat(filename, function (err, content) {
-    debug('cat done');
-    if (err) {
-      if (callback) callback(err);
-    } else {
-      var e = self._compile(content, filename);
-      if (e) {
-        if (callback) callback(e);
-      } else {
-        self._waitChildrenLoad(function () {
-          self.loaded = true;
-          if (self.onload) self.onload();
-          if (callback) callback(null, self.exports);
-        });
-      }
-    }
-  });
-};
-
-
-Module.prototype._waitChildrenLoad = function (callback) {
-  var nloaded = 0;
-  var children = this.children;
-  for (var i = 0; i < children.length; i++) {
-    var child = children[i];
-    if (child.loaded) {
-      nloaded++;
-    } else {
-      child.onload = function () {
-        child.onload = null;
-        nloaded++;
-        if (children.length == nloaded && callback) callback();
-      };
-    }
-  }
-  if (children.length == nloaded && callback) callback();
-};
-
-
 var stdout;
 process.__defineGetter__('stdout', function () {
   if (stdout) return stdout;
-  var net = requireNative('net');
+  var net = module.requireNative('net');
   stdout = new net.Stream(process.binding('stdio').stdoutFD);
   return stdout;
 });
@@ -586,7 +137,7 @@ process.__defineGetter__('stdout', function () {
 var stdin;
 process.openStdin = function () {
   if (stdin) return stdin;
-  var net = requireNative('net');
+  var net = module.requireNative('net');
   var fd = process.binding('stdio').openStdin();
   stdin = new net.Stream(fd);
   stdin.resume();
@@ -600,22 +151,9 @@ process.exit = function (code) {
   process.reallyExit(code);
 };
 
-var cwd = process.cwd();
 
-// Make process.argv[0] and process.argv[1] into full paths.
-if (process.argv[0].indexOf('/') > 0) {
-  process.argv[0] = path.join(cwd, process.argv[0]);
-}
-
-if (process.argv[1].charAt(0) != "/" && !(/^http:\/\//).exec(process.argv[1])) {
-  process.argv[1] = path.join(cwd, process.argv[1]);
-}
+module.runMain();
 
-// Load the main module--the command line argument.
-process.mainModule = new Module(".");
-process.mainModule.load(process.argv[1], function (err) {
-  if (err) throw err;
-});
 
 // All our arguments are loaded. We've evaluated all of the scripts. We
 // might even have created TCP servers. Now we enter the main eventloop. If