Browse Source

module: don't cache uninitialized builtins

Don't cache the exported values of fully uninitialized builtins.
This works by adding an additional `loading` flag that is only
active during initial loading of an internal module and checking
that either the module is fully loaded or is in that state before
using its cached value.

This has the effect that builtins modules which could not be loaded
(e.g. because compilation failed due to missing stack space) can be
loaded at a later point.

Fixes: https://github.com/nodejs/node/issues/6899
PR-URL: https://github.com/nodejs/node/pull/6907
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
v7.x
Anna Henningsen 9 years ago
parent
commit
dab09877b0
No known key found for this signature in database GPG Key ID: D8B9F5AEAE84E4CF
  1. 23
      lib/internal/bootstrap_node.js
  2. 22
      test/message/console_low_stack_space.js
  3. 1
      test/message/console_low_stack_space.out

23
lib/internal/bootstrap_node.js

@ -357,6 +357,7 @@
this.id = id;
this.exports = {};
this.loaded = false;
this.loading = false;
}
NativeModule._source = process.binding('natives');
@ -368,7 +369,7 @@
}
var cached = NativeModule.getCached(id);
if (cached) {
if (cached && (cached.loaded || cached.loading)) {
return cached.exports;
}
@ -432,14 +433,20 @@
var source = NativeModule.getSource(this.id);
source = NativeModule.wrap(source);
var fn = runInThisContext(source, {
filename: this.filename,
lineOffset: 0,
displayErrors: true
});
fn(this.exports, NativeModule.require, this, this.filename);
this.loading = true;
try {
var fn = runInThisContext(source, {
filename: this.filename,
lineOffset: 0,
displayErrors: true
});
fn(this.exports, NativeModule.require, this, this.filename);
this.loaded = true;
this.loaded = true;
} finally {
this.loading = false;
}
};
NativeModule.prototype.cache = function() {

22
test/message/console_low_stack_space.js

@ -0,0 +1,22 @@
'use strict';
// copy console accessor because requiring ../common touches it
const consoleDescriptor = Object.getOwnPropertyDescriptor(global, 'console');
delete global.console;
global.console = {};
require('../common');
function a() {
try {
return a();
} catch (e) {
const console = consoleDescriptor.get();
if (console.log) {
console.log('Hello, World!');
} else {
throw e;
}
}
}
a();

1
test/message/console_low_stack_space.out

@ -0,0 +1 @@
Hello, World!
Loading…
Cancel
Save