index.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. var natives = process.binding('natives')
  2. var module = require('module')
  3. var normalRequire = require
  4. exports.source = src
  5. exports.require = req
  6. var vm = require('vm')
  7. // fallback for 0.x support
  8. var runInThisContext, ContextifyScript, Script
  9. /*istanbul ignore next*/
  10. try {
  11. ContextifyScript = process.binding('contextify').ContextifyScript;
  12. runInThisContext = function runInThisContext(code, options) {
  13. var script = new ContextifyScript(code, options);
  14. return script.runInThisContext();
  15. }
  16. } catch (er) {
  17. Script = process.binding('evals').NodeScript;
  18. runInThisContext = Script.runInThisContext;
  19. }
  20. var wrap = [
  21. '(function (exports, require, module, __filename, __dirname) { ',
  22. '\n});'
  23. ];
  24. // Basically the same functionality as node's (buried deep)
  25. // NativeModule class, but without caching, or internal/ blocking,
  26. // or a class, since that's not really necessary. I assume that if
  27. // you're loading something with this module, it's because you WANT
  28. // a separate copy. However, to preserve semantics, any require()
  29. // calls made throughout the internal module load IS cached.
  30. function req (id, whitelist) {
  31. var cache = Object.create(null)
  32. if (Array.isArray(whitelist)) {
  33. // a whitelist of things to pull from the "actual" native modules
  34. whitelist.forEach(function (id) {
  35. cache[id] = {
  36. loading: false,
  37. loaded: true,
  38. filename: id + '.js',
  39. exports: require(id)
  40. }
  41. })
  42. }
  43. return req_(id, cache)
  44. }
  45. function req_ (id, cache) {
  46. // Buffer is special, because it's a type rather than a "normal"
  47. // class, and many things depend on `Buffer.isBuffer` working.
  48. if (id === 'buffer') {
  49. return require('buffer')
  50. }
  51. // native_module isn't actually a natives binding.
  52. // weird, right?
  53. if (id === 'native_module') {
  54. return {
  55. getSource: src,
  56. wrap: function (script) {
  57. return wrap[0] + script + wrap[1]
  58. },
  59. wrapper: wrap,
  60. _cache: cache
  61. }
  62. }
  63. var source = src(id)
  64. if (!source) {
  65. return undefined
  66. }
  67. source = wrap[0] + source + wrap[1]
  68. var cachingRequire = function require (id) {
  69. if (cache[id]) {
  70. return cache[id].exports
  71. }
  72. return req_(id, cache)
  73. }
  74. var nm = {
  75. exports: {},
  76. loading: true,
  77. loaded: false,
  78. filename: id + '.js'
  79. }
  80. cache[id] = nm
  81. var fn
  82. try {
  83. /* istanbul ignore else */
  84. if (ContextifyScript) {
  85. fn = runInThisContext(source, {
  86. filename: nm.filename,
  87. lineOffset: 0,
  88. displayErrors: true
  89. });
  90. } else {
  91. fn = runInThisContext(source, nm.filename, true);
  92. }
  93. fn(nm.exports, cachingRequire, nm, nm.filename)
  94. nm.loaded = true
  95. } finally {
  96. nm.loading = false
  97. }
  98. return nm.exports
  99. }
  100. function src (id) {
  101. return natives[id]
  102. }