diff options
author | Paul Joseph Davis <davisp@apache.org> | 2011-05-11 18:50:41 +0000 |
---|---|---|
committer | Paul Joseph Davis <davisp@apache.org> | 2011-05-11 18:50:41 +0000 |
commit | a0563ab7ce204cf82feb56259d7a52c0b84077b7 (patch) | |
tree | e02f1828721161c390785dbcf0f4e14d9be1af17 /share/server | |
parent | 52d18a368aeb1f67cb9dc35ff9135b558a196399 (diff) |
Fix circular imports in CommonJS modules.
Backport of 1102006 from trunk.
git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1102017 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'share/server')
-rw-r--r-- | share/server/util.js | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/share/server/util.js b/share/server/util.js index b55480b9..e4386701 100644 --- a/share/server/util.js +++ b/share/server/util.js @@ -31,16 +31,16 @@ var resolveModule = function(names, mod, root) { } return resolveModule(names, { id : mod.id.slice(0, mod.id.lastIndexOf('/')), - parent : mod.parent.parent.parent, - current : mod.parent.parent.current + parent : mod.parent.parent, + current : mod.parent.current }); } else if (n == '.') { if (!mod.parent) { throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(mod.current)]; } return resolveModule(names, { - parent : mod.parent.parent, - current : mod.parent.current, + parent : mod.parent, + current : mod.current, id : mod.id }); } else if (root) { @@ -66,17 +66,28 @@ var Couch = { try { if (sandbox) { if (ddoc) { + if (!ddoc._module_cache) { + ddoc._module_cache = {}; + } var require = function(name, module) { module = module || {}; - var newModule = resolveModule(name.split('/'), module, ddoc); - var s = "function (module, exports, require) { " + newModule.current + " }"; - try { - var func = sandbox ? evalcx(s, sandbox) : eval(s); - func.apply(sandbox, [newModule, newModule.exports, function(name) {return require(name, newModule)}]); - } catch(e) { - throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()]; + var newModule = resolveModule(name.split('/'), module.parent, ddoc); + if (!ddoc._module_cache.hasOwnProperty(newModule.id)) { + // create empty exports object before executing the module, + // stops circular requires from filling the stack + ddoc._module_cache[newModule.id] = {}; + var s = "function (module, exports, require) { " + newModule.current + " }"; + try { + var func = sandbox ? evalcx(s, sandbox) : eval(s); + func.apply(sandbox, [newModule, newModule.exports, function(name) { + return require(name, newModule); + }]); + } catch(e) { + throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()]; + } + ddoc._module_cache[newModule.id] = newModule.exports; } - return newModule.exports; + return ddoc._module_cache[newModule.id]; } sandbox.require = require; } |