index.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. /*istanbul ignore next*/
  13. if (process.version.split('.')[0].length > 2) { // v10.0.0 and above
  14. runInThisContext = vm.runInThisContext;
  15. } else {
  16. runInThisContext = function runInThisContext(code, options) {
  17. var script = new ContextifyScript(code, options);
  18. return script.runInThisContext();
  19. }
  20. }
  21. } catch (er) {
  22. Script = process.binding('evals').NodeScript;
  23. runInThisContext = Script.runInThisContext;
  24. }
  25. var wrap = [
  26. '(function (exports, require, module, __filename, __dirname) { ',
  27. '\n});'
  28. ];
  29. // Basically the same functionality as node's (buried deep)
  30. // NativeModule class, but without caching, or internal/ blocking,
  31. // or a class, since that's not really necessary. I assume that if
  32. // you're loading something with this module, it's because you WANT
  33. // a separate copy. However, to preserve semantics, any require()
  34. // calls made throughout the internal module load IS cached.
  35. function req (id, whitelist) {
  36. var cache = Object.create(null)
  37. if (Array.isArray(whitelist)) {
  38. // a whitelist of things to pull from the "actual" native modules
  39. whitelist.forEach(function (id) {
  40. cache[id] = {
  41. loading: false,
  42. loaded: true,
  43. filename: id + '.js',
  44. exports: require(id)
  45. }
  46. })
  47. }
  48. return req_(id, cache)
  49. }
  50. function req_ (id, cache) {
  51. // Buffer is special, because it's a type rather than a "normal"
  52. // class, and many things depend on `Buffer.isBuffer` working.
  53. if (id === 'buffer') {
  54. return require('buffer')
  55. }
  56. // native_module isn't actually a natives binding.
  57. // weird, right?
  58. if (id === 'native_module') {
  59. return {
  60. getSource: src,
  61. wrap: function (script) {
  62. return wrap[0] + script + wrap[1]
  63. },
  64. wrapper: wrap,
  65. _cache: cache,
  66. _source: natives,
  67. nonInternalExists: function (id) {
  68. return id.indexOf('internal/') !== 0;
  69. }
  70. }
  71. }
  72. var source = src(id)
  73. if (!source) {
  74. return undefined
  75. }
  76. source = wrap[0] + source + wrap[1]
  77. var cachingRequire = function require (id) {
  78. if (cache[id]) {
  79. return cache[id].exports
  80. }
  81. if (id === 'internal/bootstrap/loaders' || id === 'internal/process') {
  82. // Provide just enough to keep `graceful-fs@3` working and tests passing.
  83. // For now.
  84. return {
  85. internalBinding: function(name) {
  86. if (name === 'types') {
  87. return process.binding('util');
  88. } else {
  89. return {};
  90. }
  91. },
  92. NativeModule: {
  93. _source: process.binding('natives'),
  94. nonInternalExists: function(id) {
  95. return !id.startsWith('internal/');
  96. }
  97. }
  98. };
  99. }
  100. return req_(id, cache)
  101. }
  102. var nm = {
  103. exports: {},
  104. loading: true,
  105. loaded: false,
  106. filename: id + '.js'
  107. }
  108. cache[id] = nm
  109. var fn
  110. var setV8Flags = false
  111. try {
  112. require('v8').setFlagsFromString('--allow_natives_syntax')
  113. setV8Flags = true
  114. } catch (e) {}
  115. try {
  116. /* istanbul ignore else */
  117. if (ContextifyScript) {
  118. fn = runInThisContext(source, {
  119. filename: nm.filename,
  120. lineOffset: 0,
  121. displayErrors: true
  122. });
  123. } else {
  124. fn = runInThisContext(source, nm.filename, true);
  125. }
  126. fn(nm.exports, cachingRequire, nm, nm.filename)
  127. nm.loaded = true
  128. } finally {
  129. nm.loading = false
  130. /*istanbul ignore next*/
  131. if (setV8Flags) {
  132. // Ref: https://github.com/nodejs/node/blob/591a24b819d53a555463b1cbf9290a6d8bcc1bcb/lib/internal/bootstrap_node.js#L429-L434
  133. var re = /^--allow[-_]natives[-_]syntax$/
  134. if (!process.execArgv.some(function (s) { return re.test(s) }))
  135. require('v8').setFlagsFromString('--noallow_natives_syntax')
  136. }
  137. }
  138. return nm.exports
  139. }
  140. function src (id) {
  141. return natives[id]
  142. }