Browse Source

Isolate native module system again

See: 2e5dfafcb0 (commitcomment-239719)
v0.7.4-release
Felix Geisendörfer 14 years ago
committed by Ryan Dahl
parent
commit
f39fdf2610
  1. 158
      src/node.js

158
src/node.js

@ -76,67 +76,103 @@
process._needTickCallback(); process._needTickCallback();
}; };
// This contains the source code for the files in lib/ // Native modules don't need a full require function. So we can bootstrap
// Like, natives.fs is the contents of lib/fs.js // most of the system with this mini module system.
var natives = process.binding('natives'); var NativeModule = (function() {
function NativeModule(id) {
// Module System this.filename = id + '.js';
var Module = (function() {
function Module(id, parent) {
this.id = id; this.id = id;
this.exports = {}; this.exports = {};
this.parent = parent;
this.filename = null;
this.loaded = false; this.loaded = false;
this.exited = false; }
this.children = [];
};
// Set the environ variable NODE_MODULE_CONTEXTS=1 to make node load all NativeModule._source = process.binding('natives');
// modules in thier own context. NativeModule._cache = {};
Module._contextLoad = (+process.env['NODE_MODULE_CONTEXTS'] > 0);
Module._internalCache = {};
Module._cache = {};
Module._extensions = {};
Module._paths = [];
// Native modules don't need a full require function. So we can bootstrap NativeModule.require = function(id) {
// most of the system with this mini-require.
Module._requireNative = function(id) {
if (id == 'module') { if (id == 'module') {
return Module; return Module;
} }
if (Module._internalCache[id]) { var cached = NativeModule.getCached(id);
return Module._internalCache[id].exports; if (cached) {
return cached.exports;
} }
if (!natives[id]) { if (!NativeModule.exists(id)) {
throw new Error('No such native module ' + id); throw new Error('No such native module ' + id);
} }
var filename = id + '.js'; var nativeModule = new NativeModule(id);
var fn = runInThisContext(Module.wrap(natives[id]), filename, true); nativeModule.compile();
nativeModule.cache();
var m = {id: id, exports: {}}; return nativeModule.exports;
fn(m.exports, Module._requireNative, m, filename);
m.loaded = true;
Module._internalCache[id] = m;
return m.exports;
}; };
Module.wrap = function(script) { NativeModule.getCached = function(id) {
return Module.wrapper[0] + script + Module.wrapper[1]; return NativeModule._cache[id];
}
NativeModule.exists = function(id) {
return (id in NativeModule._source);
}
NativeModule.getSource = function(id) {
return NativeModule._source[id];
}
NativeModule.wrap = function(script) {
return NativeModule.wrapper[0] + script + NativeModule.wrapper[1];
}; };
Module.wrapper = [ NativeModule.wrapper = [
'(function (exports, require, module, __filename, __dirname) { ', '(function (exports, require, module, __filename, __dirname) { ',
'\n});' '\n});'
]; ];
var path = Module._requireNative('path'); NativeModule.prototype.compile = function() {
var source = NativeModule.getSource(this.id);
source = NativeModule.wrap(source);
var fn = runInThisContext(source, this.filename, true);
fn(this.exports, NativeModule.require, this, this.filename);
this.loaded = true;
};
NativeModule.prototype.cache = function() {
NativeModule._cache[this.id] = this;
};
return NativeModule;
})();
// Module System
var Module = (function() {
function Module(id, parent) {
this.id = id;
this.exports = {};
this.parent = parent;
this.filename = null;
this.loaded = false;
this.exited = false;
this.children = [];
};
// Set the environ variable NODE_MODULE_CONTEXTS=1 to make node load all
// modules in thier own context.
Module._contextLoad = (+process.env['NODE_MODULE_CONTEXTS'] > 0);
Module._cache = {};
Module._extensions = {};
Module._paths = [];
Module.wrapper = NativeModule.wrapper;
Module.wrap = NativeModule.wrap;
var path = NativeModule.require('path');
Module._debug = function() {}; Module._debug = function() {};
if (process.env.NODE_DEBUG && /module/.test(process.env.NODE_DEBUG)) { if (process.env.NODE_DEBUG && /module/.test(process.env.NODE_DEBUG)) {
@ -159,7 +195,7 @@
// -> a.<ext> // -> a.<ext>
// -> a/index.<ext> // -> a/index.<ext>
Module._findPath = function(request, paths) { Module._findPath = function(request, paths) {
var fs = Module._requireNative('fs'); var fs = NativeModule.require('fs');
var exts = Object.keys(Module._extensions); var exts = Object.keys(Module._extensions);
if (request.charAt(0) === '/') { if (request.charAt(0) === '/') {
@ -201,7 +237,7 @@
} }
Module._resolveLookupPaths = function(request, parent) { Module._resolveLookupPaths = function(request, parent) {
if (natives[request]) { if (NativeModule.exists(request)) {
return [request, []]; return [request, []];
} }
@ -250,19 +286,17 @@
return cachedModule.exports; return cachedModule.exports;
} }
// With natives id === request if (NativeModule.exists(id)) {
// We deal with these first
if (natives[id]) {
// REPL is a special case, because it needs the real require. // REPL is a special case, because it needs the real require.
if (id == 'repl') { if (id == 'repl') {
var replModule = new Module('repl'); var replModule = new Module('repl');
replModule._compile(natives.repl, 'repl.js'); replModule._compile(NativeModule.getSource('repl'), 'repl.js');
Module._internalCache.repl = replModule; NativeModule._cache.repl = replModule;
return replModule.exports; return replModule.exports;
} }
debug('load native module ' + request); debug('load native module ' + request);
return Module._requireNative(id); return NativeModule.require(id);
} }
var module = new Module(id, parent); var module = new Module(id, parent);
@ -272,7 +306,7 @@
}; };
Module._resolveFilename = function(request, parent) { Module._resolveFilename = function(request, parent) {
if (natives[request]) { if (NativeModule.exists(request)) {
return [request, request]; return [request, request];
} }
@ -375,7 +409,7 @@
// Native extension for .js // Native extension for .js
Module._extensions['.js'] = function(module, filename) { Module._extensions['.js'] = function(module, filename) {
var content = Module._requireNative('fs').readFileSync(filename, 'utf8'); var content = NativeModule.require('fs').readFileSync(filename, 'utf8');
module._compile(content, filename); module._compile(content, filename);
}; };
@ -424,7 +458,7 @@
// Load events module in order to access prototype elements on process like // Load events module in order to access prototype elements on process like
// process.addListener. // process.addListener.
var events = Module._requireNative('events'); var events = NativeModule.require('events');
// Signal Handlers // Signal Handlers
(function() { (function() {
@ -471,22 +505,22 @@
global.setTimeout = function() { global.setTimeout = function() {
var t = Module._requireNative('timers'); var t = NativeModule.require('timers');
return t.setTimeout.apply(this, arguments); return t.setTimeout.apply(this, arguments);
}; };
global.setInterval = function() { global.setInterval = function() {
var t = Module._requireNative('timers'); var t = NativeModule.require('timers');
return t.setInterval.apply(this, arguments); return t.setInterval.apply(this, arguments);
}; };
global.clearTimeout = function() { global.clearTimeout = function() {
var t = Module._requireNative('timers'); var t = NativeModule.require('timers');
return t.clearTimeout.apply(this, arguments); return t.clearTimeout.apply(this, arguments);
}; };
global.clearInterval = function() { global.clearInterval = function() {
var t = Module._requireNative('timers'); var t = NativeModule.require('timers');
return t.clearInterval.apply(this, arguments); return t.clearInterval.apply(this, arguments);
}; };
@ -498,8 +532,8 @@
if (stdout) return stdout; if (stdout) return stdout;
var binding = process.binding('stdio'), var binding = process.binding('stdio'),
net = Module._requireNative('net'), net = NativeModule.require('net'),
fs = Module._requireNative('fs'), fs = NativeModule.require('fs'),
fd = binding.stdoutFD; fd = binding.stdoutFD;
if (binding.isStdoutBlocking()) { if (binding.isStdoutBlocking()) {
@ -521,8 +555,8 @@
if (stdin) return stdin; if (stdin) return stdin;
var binding = process.binding('stdio'), var binding = process.binding('stdio'),
net = Module._requireNative('net'), net = NativeModule.require('net'),
fs = Module._requireNative('fs'), fs = NativeModule.require('fs'),
fd = binding.openStdin(); fd = binding.openStdin();
if (binding.isStdinBlocking()) { if (binding.isStdinBlocking()) {
@ -544,11 +578,11 @@
// Lazy load console object // Lazy load console object
global.__defineGetter__('console', function() { global.__defineGetter__('console', function() {
return Module._requireNative('console'); return NativeModule.require('console');
}); });
global.Buffer = Module._requireNative('buffer').Buffer; global.Buffer = NativeModule.require('buffer').Buffer;
process.exit = function(code) { process.exit = function(code) {
process.emit('exit', code || 0); process.emit('exit', code || 0);
@ -563,7 +597,7 @@
var cwd = process.cwd(); var cwd = process.cwd();
var path = Module._requireNative('path'); var path = NativeModule.require('path');
var isWindows = process.platform === 'win32'; var isWindows = process.platform === 'win32';
// Make process.argv[0] and process.argv[1] into full paths, but only // Make process.argv[0] and process.argv[1] into full paths, but only
@ -579,9 +613,9 @@
// To allow people to extend Node in different ways, this hook allows // To allow people to extend Node in different ways, this hook allows
// one to drop a file lib/_third_party_main.js into the build directory // one to drop a file lib/_third_party_main.js into the build directory
// which will be executed instead of Node's normal loading. // which will be executed instead of Node's normal loading.
if (process.binding('natives')['_third_party_main']) { if (NativeModule.exists('_third_party_main')) {
process.nextTick(function () { process.nextTick(function () {
Module._requireNative('_third_party_main'); NativeModule.require('_third_party_main');
}); });
return; return;
} }
@ -589,7 +623,7 @@
if (process.argv[1]) { if (process.argv[1]) {
if (process.argv[1] == 'debug') { if (process.argv[1] == 'debug') {
// Start the debugger agent // Start the debugger agent
var d = Module._requireNative('_debugger'); var d = NativeModule.require('_debugger');
d.start(); d.start();
return; return;
} }

Loading…
Cancel
Save