From a0563ab7ce204cf82feb56259d7a52c0b84077b7 Mon Sep 17 00:00:00 2001 From: Paul Joseph Davis Date: Wed, 11 May 2011 18:50:41 +0000 Subject: 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 --- share/server/util.js | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'share/server/util.js') 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; } -- cgit v1.2.3