iojs: introduce internal modules
Internal modules can be used to share private code between public modules without risk to expose private APIs to the user. PR-URL: https://github.com/iojs/io.js/pull/848 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
parent
45814216ee
commit
2db758c562
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const FreeList = require('freelist').FreeList;
|
const FreeList = require('internal/freelist').FreeList;
|
||||||
const HTTPParser = process.binding('http_parser').HTTPParser;
|
const HTTPParser = process.binding('http_parser').HTTPParser;
|
||||||
|
|
||||||
const incoming = require('_http_incoming');
|
const incoming = require('_http_incoming');
|
||||||
|
@ -1,26 +1,3 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// This is a free list to avoid creating so many of the same object.
|
module.exports = require('internal/freelist');
|
||||||
exports.FreeList = function(name, max, constructor) {
|
|
||||||
this.name = name;
|
|
||||||
this.constructor = constructor;
|
|
||||||
this.max = max;
|
|
||||||
this.list = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
exports.FreeList.prototype.alloc = function() {
|
|
||||||
//debug("alloc " + this.name + " " + this.list.length);
|
|
||||||
return this.list.length ? this.list.shift() :
|
|
||||||
this.constructor.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
exports.FreeList.prototype.free = function(obj) {
|
|
||||||
//debug("free " + this.name + " " + this.list.length);
|
|
||||||
if (this.list.length < this.max) {
|
|
||||||
this.list.push(obj);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
24
lib/internal/freelist.js
Normal file
24
lib/internal/freelist.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
// This is a free list to avoid creating so many of the same object.
|
||||||
|
exports.FreeList = function(name, max, constructor) {
|
||||||
|
this.name = name;
|
||||||
|
this.constructor = constructor;
|
||||||
|
this.max = max;
|
||||||
|
this.list = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
exports.FreeList.prototype.alloc = function() {
|
||||||
|
return this.list.length ? this.list.shift() :
|
||||||
|
this.constructor.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
exports.FreeList.prototype.free = function(obj) {
|
||||||
|
if (this.list.length < this.max) {
|
||||||
|
this.list.push(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
@ -200,7 +200,7 @@ Module._nodeModulePaths = function(from) {
|
|||||||
|
|
||||||
|
|
||||||
Module._resolveLookupPaths = function(request, parent) {
|
Module._resolveLookupPaths = function(request, parent) {
|
||||||
if (NativeModule.exists(request)) {
|
if (NativeModule.nonInternalExists(request)) {
|
||||||
return [request, []];
|
return [request, []];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ Module._load = function(request, parent, isMain) {
|
|||||||
return cachedModule.exports;
|
return cachedModule.exports;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NativeModule.exists(filename)) {
|
if (NativeModule.nonInternalExists(filename)) {
|
||||||
// REPL is a special case, because it needs the real require.
|
// REPL is a special case, because it needs the real require.
|
||||||
if (filename == 'repl') {
|
if (filename == 'repl') {
|
||||||
var replModule = new Module('repl');
|
var replModule = new Module('repl');
|
||||||
@ -299,7 +299,7 @@ Module._load = function(request, parent, isMain) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Module._resolveFilename = function(request, parent) {
|
Module._resolveFilename = function(request, parent) {
|
||||||
if (NativeModule.exists(request)) {
|
if (NativeModule.nonInternalExists(request)) {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
node.gyp
2
node.gyp
@ -69,6 +69,8 @@
|
|||||||
'lib/v8.js',
|
'lib/v8.js',
|
||||||
'lib/vm.js',
|
'lib/vm.js',
|
||||||
'lib/zlib.js',
|
'lib/zlib.js',
|
||||||
|
|
||||||
|
'lib/internal/freelist.js',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -3133,6 +3133,9 @@ static void ParseArgs(int* argc,
|
|||||||
} else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
|
} else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
|
||||||
icu_data_dir = arg + 15;
|
icu_data_dir = arg + 15;
|
||||||
#endif
|
#endif
|
||||||
|
} else if (strcmp(arg, "--expose-internals") == 0 ||
|
||||||
|
strcmp(arg, "--expose_internals") == 0) {
|
||||||
|
// consumed in js
|
||||||
} else {
|
} else {
|
||||||
// V8 option. Pass through as-is.
|
// V8 option. Pass through as-is.
|
||||||
new_v8_argv[new_v8_argc] = arg;
|
new_v8_argv[new_v8_argc] = arg;
|
||||||
|
21
src/node.js
21
src/node.js
@ -838,6 +838,27 @@
|
|||||||
return NativeModule._source.hasOwnProperty(id);
|
return NativeModule._source.hasOwnProperty(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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) {
|
NativeModule.getSource = function(id) {
|
||||||
return NativeModule._source[id];
|
return NativeModule._source[id];
|
||||||
};
|
};
|
||||||
|
1
test/fixtures/internal-modules/index.js
vendored
Normal file
1
test/fixtures/internal-modules/index.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = require('internal/freelist');
|
1
test/fixtures/internal-modules/node_modules/internal/freelist.js
generated
vendored
Normal file
1
test/fixtures/internal-modules/node_modules/internal/freelist.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = 42;
|
6
test/parallel/test-internal-modules-expose.js
Normal file
6
test/parallel/test-internal-modules-expose.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Flags: --expose_internals
|
||||||
|
|
||||||
|
var common = require('../common');
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
assert.equal(typeof require('internal/freelist').FreeList, 'function');
|
8
test/parallel/test-internal-modules.js
Normal file
8
test/parallel/test-internal-modules.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
var common = require('../common');
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
assert.throws(function() {
|
||||||
|
require('internal/freelist');
|
||||||
|
});
|
||||||
|
|
||||||
|
assert(require('../fixtures/internal-modules') === 42);
|
@ -238,11 +238,11 @@ static const struct _native natives[] = {
|
|||||||
|
|
||||||
|
|
||||||
NATIVE_DECLARATION = """\
|
NATIVE_DECLARATION = """\
|
||||||
{ "%(id)s", %(id)s_native, sizeof(%(id)s_native)-1 },
|
{ "%(id)s", %(escaped_id)s_native, sizeof(%(escaped_id)s_native)-1 },
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SOURCE_DECLARATION = """\
|
SOURCE_DECLARATION = """\
|
||||||
const char %(id)s_native[] = { %(data)s };
|
const char %(escaped_id)s_native[] = { %(data)s };
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@ -293,16 +293,29 @@ def JS2C(source, target):
|
|||||||
lines = ExpandMacros(lines, macros)
|
lines = ExpandMacros(lines, macros)
|
||||||
lines = CompressScript(lines, do_jsmin)
|
lines = CompressScript(lines, do_jsmin)
|
||||||
data = ToCArray(s, lines)
|
data = ToCArray(s, lines)
|
||||||
id = os.path.basename(str(s)).split('.')[0]
|
id = '/'.join(re.split('/|\\\\', s)[1:]).split('.')[0]
|
||||||
if delay: id = id[:-6]
|
if delay: id = id[:-6]
|
||||||
if delay:
|
if delay:
|
||||||
delay_ids.append((id, len(lines)))
|
delay_ids.append((id, len(lines)))
|
||||||
else:
|
else:
|
||||||
ids.append((id, len(lines)))
|
ids.append((id, len(lines)))
|
||||||
source_lines.append(SOURCE_DECLARATION % { 'id': id, 'data': data })
|
|
||||||
source_lines_empty.append(SOURCE_DECLARATION % { 'id': id, 'data': 0 })
|
escaped_id = id.replace('/', '$')
|
||||||
native_lines.append(NATIVE_DECLARATION % { 'id': id })
|
source_lines.append(SOURCE_DECLARATION % {
|
||||||
|
'id': id,
|
||||||
|
'escaped_id': escaped_id,
|
||||||
|
'data': data
|
||||||
|
})
|
||||||
|
source_lines_empty.append(SOURCE_DECLARATION % {
|
||||||
|
'id': id,
|
||||||
|
'escaped_id': escaped_id,
|
||||||
|
'data': 0
|
||||||
|
})
|
||||||
|
native_lines.append(NATIVE_DECLARATION % {
|
||||||
|
'id': id,
|
||||||
|
'escaped_id': escaped_id
|
||||||
|
})
|
||||||
|
|
||||||
# Build delay support functions
|
# Build delay support functions
|
||||||
get_index_cases = [ ]
|
get_index_cases = [ ]
|
||||||
get_script_source_cases = [ ]
|
get_script_source_cases = [ ]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user