index.js 4.2 KB

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