|
|
@ -71,6 +71,16 @@ clearInterval = clearTimeout; |
|
|
|
|
|
|
|
// Module
|
|
|
|
|
|
|
|
node.libraryPaths = [ node.path.join(ENV["HOME"], ".node_libraries") |
|
|
|
, node.path.join(node.installPrefix, "lib/node_libraries") |
|
|
|
, "/" |
|
|
|
]; |
|
|
|
|
|
|
|
if (ENV["NODE_LIBRARY_PATHS"]) { |
|
|
|
node.libraryPaths = |
|
|
|
ENV["NODE_LIBRARY_PATHS"].split(":").concat(node.libraryPaths); |
|
|
|
} |
|
|
|
|
|
|
|
node.loadingModules = []; |
|
|
|
|
|
|
|
function require_async (url) { |
|
|
@ -83,49 +93,125 @@ function require (url) { |
|
|
|
} |
|
|
|
|
|
|
|
function include_async (url) { |
|
|
|
var currentModule = node.loadingModules[0]; |
|
|
|
return currentModule.newChild(url, currentModule.target); |
|
|
|
var promise = require_async(url) |
|
|
|
promise.addCallback(function (t) { |
|
|
|
// copy properties into global namespace.
|
|
|
|
for (var prop in t) { |
|
|
|
if (t.hasOwnProperty(prop)) process[prop] = t[prop]; |
|
|
|
} |
|
|
|
}); |
|
|
|
return promise; |
|
|
|
} |
|
|
|
|
|
|
|
function include (url) { |
|
|
|
include_async(url).wait(); |
|
|
|
} |
|
|
|
|
|
|
|
node.Module = function (o) { |
|
|
|
this.parent = o.parent; |
|
|
|
this.target = o.target || {}; |
|
|
|
node.Module = function (filename, parent) { |
|
|
|
node.assert(filename.charAt(0) == "/"); |
|
|
|
this.filename = filename; |
|
|
|
this.target = {}; |
|
|
|
this.parent = parent; |
|
|
|
|
|
|
|
if (!o.path) throw "path argument required"; |
|
|
|
this.loaded = false; |
|
|
|
this.loadPromise = null; |
|
|
|
this.exited = false; |
|
|
|
this.children = []; |
|
|
|
}; |
|
|
|
|
|
|
|
node.Module.cache = {}; |
|
|
|
|
|
|
|
if (o.path.charAt(0) == "/") { |
|
|
|
throw "Absolute module paths are not yet supported by Node"; |
|
|
|
(function () { |
|
|
|
function retrieveFromCache (loadPromise, fullPath, parent) { |
|
|
|
var module; |
|
|
|
if (fullPath in node.Module.cache) { |
|
|
|
module = node.Module.cache[fullPath]; |
|
|
|
setTimeout(function () { |
|
|
|
loadPromise.emitSuccess(module.target); |
|
|
|
}, 0); |
|
|
|
} else { |
|
|
|
module = new node.Module(fullPath, parent); |
|
|
|
node.Module.cache[fullPath] = module; |
|
|
|
module.load(loadPromise); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (o.path.match(/:\/\//)) { |
|
|
|
this.filename = o.path; |
|
|
|
function findPath (path, dirs, callback) { |
|
|
|
node.assert(path.charAt(0) == "/"); |
|
|
|
node.assert(dirs.constructor == Array); |
|
|
|
|
|
|
|
if (dirs.length == 0) { |
|
|
|
callback(); |
|
|
|
} else { |
|
|
|
var dir = dirs[0]; |
|
|
|
var rest = dirs.slice(1, dirs.length); |
|
|
|
|
|
|
|
var fullPath = node.path.join(dir, path); |
|
|
|
node.fs.exists(fullPath, function (doesExist) { |
|
|
|
if (doesExist) { |
|
|
|
callback(fullPath); |
|
|
|
} else { |
|
|
|
var dir = o.base_directory || "."; |
|
|
|
this.filename = node.path.join(dir, o.path); |
|
|
|
findPath(path, rest, callback); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
this.loaded = false; |
|
|
|
this.loadPromise = null; |
|
|
|
this.exited = false; |
|
|
|
this.children = []; |
|
|
|
node.loadModule = function (requestedPath, target, parent) { |
|
|
|
var loadPromise = new node.Promise(); |
|
|
|
|
|
|
|
// On success copy the loaded properties into the target
|
|
|
|
loadPromise.addCallback(function (t) { |
|
|
|
for (var prop in t) { |
|
|
|
if (t.hasOwnProperty(prop)) target[prop] = t[prop]; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
if (!parent) { |
|
|
|
// root module
|
|
|
|
node.assert(requestedPath.charAt(0) == "/"); |
|
|
|
retrieveFromCache(loadPromise, requestedPath); |
|
|
|
|
|
|
|
} else { |
|
|
|
if (requestedPath.charAt(0) == "/") { |
|
|
|
// Need to find the module in node.libraryPaths
|
|
|
|
findPath(requestedPath, node.libraryPaths, function (fullPath) { |
|
|
|
if (fullPath) { |
|
|
|
retrieveFromCache(loadPromise, fullPath, parent); |
|
|
|
} else { |
|
|
|
loadPromise.emitError(); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
} else { |
|
|
|
// Relative file load
|
|
|
|
var fullPath = node.path.join(node.path.dirname(parent.filename), |
|
|
|
requestedPath); |
|
|
|
retrieveFromCache(loadPromise, fullPath, parent); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return loadPromise; |
|
|
|
}; |
|
|
|
}()); |
|
|
|
|
|
|
|
node.Module.prototype.load = function (loadPromise) { |
|
|
|
if (this.loaded) { |
|
|
|
loadPromise.emitError(new Error("Module '" + self.filename + "' is already loaded.")); |
|
|
|
return; |
|
|
|
} |
|
|
|
node.assert(!node.loadPromise); |
|
|
|
this.loadPromise = loadPromise; |
|
|
|
|
|
|
|
node.Module.prototype.load = function (callback) { |
|
|
|
if (this.filename.match(/\.node$/)) { |
|
|
|
return this.loadObject(callback); |
|
|
|
this.loadObject(loadPromise); |
|
|
|
} else { |
|
|
|
return this.loadScript(callback); |
|
|
|
this.loadScript(loadPromise); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
node.Module.prototype.loadObject = function (callback) { |
|
|
|
node.Module.prototype.loadObject = function (loadPromise) { |
|
|
|
var self = this; |
|
|
|
var loadPromise = new node.Promise(); |
|
|
|
self.loadPromise = loadPromise; |
|
|
|
// XXX Not yet supporting loading from HTTP. would need to download the
|
|
|
|
// file, store it to tmp then run dlopen on it.
|
|
|
|
node.fs.exists(self.filename, function (does_exist) { |
|
|
@ -139,57 +225,28 @@ node.Module.prototype.loadObject = function (callback) { |
|
|
|
node.exit(1); |
|
|
|
} |
|
|
|
}); |
|
|
|
return loadPromise; |
|
|
|
}; |
|
|
|
|
|
|
|
node.Module.prototype.loadScript = function (callback) { |
|
|
|
node.Module.prototype.loadScript = function (loadPromise) { |
|
|
|
var self = this; |
|
|
|
if (self.loaded) { |
|
|
|
throw "Module '" + self.filename + "' is already loaded."; |
|
|
|
} |
|
|
|
|
|
|
|
var loadPromise = new node.Promise(); |
|
|
|
node.assert(self.loadPromise === null); |
|
|
|
self.loadPromise = loadPromise; |
|
|
|
|
|
|
|
var cat_promise = node.cat(self.filename); |
|
|
|
var catPromise = node.cat(self.filename); |
|
|
|
|
|
|
|
cat_promise.addErrback(function () { |
|
|
|
node.stdio.writeError("Error reading " + self.filename + "\n"); |
|
|
|
loadPromise.emitError(); |
|
|
|
node.exit(1); |
|
|
|
catPromise.addErrback(function () { |
|
|
|
loadPromise.emitError(new Error("Error reading " + self.filename + "\n")); |
|
|
|
}); |
|
|
|
|
|
|
|
cat_promise.addCallback(function (content) { |
|
|
|
catPromise.addCallback(function (content) { |
|
|
|
// remove shebang
|
|
|
|
content = content.replace(/^\#\!.*/, ''); |
|
|
|
|
|
|
|
// create wrapper function
|
|
|
|
var wrapper = "function (__filename) { "+ |
|
|
|
" var onLoad; "+ |
|
|
|
" var onExit; "+ |
|
|
|
" var exports = this; "+ |
|
|
|
content+ |
|
|
|
"\n"+ |
|
|
|
" this.__onLoad = onLoad;\n"+ |
|
|
|
" this.__onExit = onExit;\n"+ |
|
|
|
"};\n"; |
|
|
|
var wrapper = "function (__filename, exports) { " + content + "\n};"; |
|
|
|
var compiled_wrapper = node.compile(wrapper, self.filename); |
|
|
|
|
|
|
|
node.loadingModules.unshift(self); |
|
|
|
compiled_wrapper.apply(self.target, [self.filename]); |
|
|
|
compiled_wrapper.apply(self.target, [self.filename, self.target]); |
|
|
|
node.loadingModules.shift(); |
|
|
|
|
|
|
|
self.onLoad = self.target.__onLoad; |
|
|
|
self.onExit = self.target.__onExit; |
|
|
|
if (self.onLoad || self.onExit) { |
|
|
|
node.stdio.writeError( "(node) onLoad and onExit have been removed. " |
|
|
|
+ " module load is synchronous so onLoad is unnecessary" |
|
|
|
+ " Use process.addListener('exit') for onExit. " |
|
|
|
); |
|
|
|
node.exit(1); |
|
|
|
} |
|
|
|
|
|
|
|
self.waitChildrenLoad(function () { |
|
|
|
self.loaded = true; |
|
|
|
loadPromise.emitSuccess(self.target); |
|
|
@ -198,15 +255,7 @@ node.Module.prototype.loadScript = function (callback) { |
|
|
|
}; |
|
|
|
|
|
|
|
node.Module.prototype.newChild = function (path, target) { |
|
|
|
var child = new node.Module({ |
|
|
|
target: target, |
|
|
|
path: path, |
|
|
|
base_directory: node.path.dirname(this.filename), |
|
|
|
parent: this |
|
|
|
}); |
|
|
|
this.children.push(child); |
|
|
|
child.load(); |
|
|
|
return child.loadPromise; |
|
|
|
return node.loadModule(path, target, this); |
|
|
|
}; |
|
|
|
|
|
|
|
node.Module.prototype.waitChildrenLoad = function (callback) { |
|
|
@ -227,22 +276,19 @@ node.Module.prototype.waitChildrenLoad = function (callback) { |
|
|
|
}; |
|
|
|
|
|
|
|
(function () { |
|
|
|
var cwd = node.cwd(); |
|
|
|
|
|
|
|
// Make ARGV[0] and ARGV[1] into full paths.
|
|
|
|
if (ARGV[0].charAt(0) != "/") { |
|
|
|
ARGV[0] = node.path.join(node.cwd(), ARGV[0]); |
|
|
|
ARGV[0] = node.path.join(cwd, ARGV[0]); |
|
|
|
} |
|
|
|
|
|
|
|
if (ARGV[1].charAt(0) != "/") { |
|
|
|
ARGV[1] = node.path.join(node.cwd(), ARGV[1]); |
|
|
|
ARGV[1] = node.path.join(cwd, ARGV[1]); |
|
|
|
} |
|
|
|
|
|
|
|
// Load the root module--the command line argument.
|
|
|
|
var root_module = new node.Module({ |
|
|
|
path: node.path.filename(ARGV[1]), |
|
|
|
base_directory: node.path.dirname(ARGV[1]), |
|
|
|
target: this |
|
|
|
}); |
|
|
|
root_module.load(); |
|
|
|
node.loadModule(ARGV[1], process); |
|
|
|
|
|
|
|
node.exit = function (code) { |
|
|
|
process.emit("exit"); |
|
|
|