255 lines
7.2 KiB
JavaScript
255 lines
7.2 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
const {coreModulesPath, runInThisContext, runInThisContextRes, _coreModulesInRes} = process.binding('modules');
|
|
const {loadFile} = process.binding('fs');
|
|
let Module;
|
|
|
|
|
|
/**
|
|
* @namespace process
|
|
* @property {string} startupPath Use a process.cwd() instead
|
|
* @property {string} execPath The main executable full path (including .exe file name)
|
|
*/
|
|
|
|
function startup() {
|
|
/**
|
|
* Current working directory
|
|
* @return {string|String}
|
|
*/
|
|
process.cwd = function () {
|
|
return process.startupPath;
|
|
};
|
|
/**
|
|
* List of loaded via `require` modules
|
|
* @private
|
|
* @type {Array<string>}
|
|
*/
|
|
process.moduleLoadList = [];
|
|
|
|
Module = NativeModule.require('module');
|
|
Module.call(global, ['.']);
|
|
process.mainModule = global;
|
|
|
|
//noinspection JSUndeclaredVariable
|
|
/**
|
|
* Load a module. Acts like a <a href="http://nodejs.org/api/modules.html">Node JS</a> require, with 1 difference:
|
|
*
|
|
* - in case we run in production mode (`!process.isDebug`) and minimized version of main module exists, it will be loaded.
|
|
* By "minimized version" we mean package.json `main` entry with `.min.js` extension <br>
|
|
*
|
|
* *In case you need to debug from there module is loaded set OS Environment variable*
|
|
* `>SET NODE_DEBUG=modules` *and restart server - require will put to debug log all information about how module are loaded.* Do not do this on production, of course :)
|
|
*
|
|
* @global
|
|
* @method
|
|
* @param {String} moduleName
|
|
* @returns {*}
|
|
*/
|
|
global.require = Module.prototype.require;
|
|
global.Buffer = NativeModule.require('buffer').Buffer;
|
|
//global.clearTimeout = function() {};
|
|
|
|
/**
|
|
* Block thread for a specified number of milliseconds
|
|
* @param {Number} ms millisecond to sleep
|
|
* @global
|
|
*/
|
|
global.sleep = process.binding('syNode').sleep;
|
|
|
|
const EventEmitter = NativeModule.require('events').EventEmitter;
|
|
// add EventEmitter to process object
|
|
EventEmitter.call(process);
|
|
Object.assign(process, EventEmitter.prototype);
|
|
|
|
const WindowTimer = NativeModule.require('polyfill/WindowTimer');
|
|
global._timerLoop = WindowTimer.makeWindowTimer(global, function (ms) { global.sleep(ms); });
|
|
/**
|
|
* This function is just to be compatible with node.js
|
|
* @param {Function} callback Callback (called immediately in SyNode)
|
|
*/
|
|
process.nextTick = function(callback, arg1, arg2, arg3){
|
|
if (typeof callback !== 'function') {
|
|
throw new TypeError('"callback" argument must be a function');
|
|
}
|
|
// on the way out, don't bother. it won't get fired anyway.
|
|
if (process._exiting)
|
|
return;
|
|
|
|
var i, args;
|
|
|
|
switch (arguments.length) {
|
|
// fast cases
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
args = [arg1];
|
|
break;
|
|
case 3:
|
|
args = [arg1, arg2];
|
|
break;
|
|
default:
|
|
args = [arg1, arg2, arg3];
|
|
for (i = 4; i < arguments.length; i++)
|
|
args[i - 1] = arguments[i];
|
|
break;
|
|
}
|
|
global._timerLoop.setTimeoutWithPriority.apply(undefined, [callback, 0, -1].concat(args));
|
|
};
|
|
|
|
/**
|
|
* This function is to be compatible with node.js
|
|
* @global
|
|
* @param {Function} callback
|
|
* @param {...*} arg
|
|
* @return {Number} immediateId
|
|
*/
|
|
global.setImmediate = function(callback, arg1, arg2, arg3){
|
|
if (typeof callback !== 'function') {
|
|
throw new TypeError('"callback" argument must be a function');
|
|
}
|
|
// on the way out, don't bother. it won't get fired anyway.
|
|
if (process._exiting)
|
|
return;
|
|
|
|
var i, args;
|
|
|
|
switch (arguments.length) {
|
|
// fast cases
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
args = [arg1];
|
|
break;
|
|
case 3:
|
|
args = [arg1, arg2];
|
|
break;
|
|
default:
|
|
args = [arg1, arg2, arg3];
|
|
for (i = 4; i < arguments.length; i++)
|
|
args[i - 1] = arguments[i];
|
|
break;
|
|
}
|
|
global._timerLoop.setTimeoutWithPriority.apply(undefined, [callback, 0, 1].concat(args));
|
|
};
|
|
|
|
}
|
|
|
|
|
|
function NativeModule(id) {
|
|
this.filename = id + '.js';
|
|
this.id = id;
|
|
this.exports = {};
|
|
this.loaded = false;
|
|
}
|
|
|
|
const NODE_CORE_MODULES = ['fs', 'util', 'path', 'assert', 'module', 'console', 'events','vm',
|
|
'net', 'os', 'punycode', 'querystring', 'timers', 'tty', 'url', 'child_process', 'http', 'https',
|
|
'crypto', 'zlib', 'dns', //fake modules
|
|
'buffer', 'string_decoder', 'internal/util', 'internal/module', 'stream', '_stream_readable', '_stream_writable',
|
|
'internal/streams/BufferList', '_stream_duplex', '_stream_transform', '_stream_passthrough',
|
|
'internal/fs',
|
|
'internal/errors', 'internal/querystring',
|
|
'polyfill/WindowTimer'];
|
|
|
|
NativeModule._source = {};
|
|
const PATH_DELIM = process.platform === 'win32' ? '\\' : '/'
|
|
NODE_CORE_MODULES.forEach( (module_name) => {
|
|
NativeModule._source[module_name] = _coreModulesInRes
|
|
? `node_modules/${module_name}.js`.toUpperCase()
|
|
: `${coreModulesPath}${PATH_DELIM}node_modules${PATH_DELIM}${module_name}.js`
|
|
});
|
|
|
|
NativeModule._cache = {};
|
|
|
|
NativeModule.require = function (id) {
|
|
if (id == 'native_module') {
|
|
return NativeModule;
|
|
}
|
|
|
|
var cached = NativeModule.getCached(id);
|
|
if (cached) {
|
|
return cached.exports;
|
|
}
|
|
|
|
if (!NativeModule.exists(id)) {
|
|
throw new Error('No such native module ' + id);
|
|
}
|
|
|
|
process.moduleLoadList.push('NativeModule ' + id);
|
|
|
|
var nativeModule = new NativeModule(id);
|
|
|
|
nativeModule.cache();
|
|
nativeModule.compile();
|
|
|
|
return nativeModule.exports;
|
|
};
|
|
|
|
NativeModule.getCached = function (id) {
|
|
if (NativeModule._cache.hasOwnProperty(id)) {
|
|
return NativeModule._cache[id]
|
|
} else {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
NativeModule.exists = function (id) {
|
|
return NativeModule._source.hasOwnProperty(id);
|
|
};
|
|
|
|
const EXPOSE_INTERNALS = false;
|
|
/* MPV
|
|
const EXPOSE_INTERNALS = process.execArgv.some(function(arg) {
|
|
return arg.match(/^--expose[-_]internals$/);
|
|
});
|
|
*/
|
|
if (EXPOSE_INTERNALS) {
|
|
NativeModule.nonInternalExists = NativeModule.exists;
|
|
|
|
NativeModule.isInternal = function(id) {
|
|
return false;
|
|
};
|
|
} else {
|
|
NativeModule.nonInternalExists = function(id) {
|
|
return NativeModule.exists(id) && !NativeModule.isInternal(id);
|
|
};
|
|
|
|
NativeModule.isInternal = function(id) {
|
|
return id.startsWith('internal/');
|
|
};
|
|
}
|
|
|
|
NativeModule.getSource = function (id) {
|
|
return loadFile(NativeModule._source[id]);
|
|
};
|
|
|
|
NativeModule.wrap = function (script) {
|
|
return NativeModule.wrapper[0] + script + NativeModule.wrapper[1];
|
|
};
|
|
|
|
NativeModule.wrapper = [
|
|
'(function (exports, require, module, __filename, __dirname) { ', '\n});'
|
|
];
|
|
|
|
NativeModule.prototype.compile = function () {
|
|
let fn;
|
|
if (_coreModulesInRes) {
|
|
fn = runInThisContextRes(NativeModule._source[this.id], this.filename, true);
|
|
} else {
|
|
let source = NativeModule.getSource(this.id);
|
|
source = NativeModule.wrap(source);
|
|
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;
|
|
};
|
|
|
|
startup();
|
|
///patch ModuleLoader
|