Created
April 29, 2012 21:23
-
-
Save rehanift/2553335 to your computer and use it in GitHub Desktop.
Using contextify to replace vm second version
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var vm = function(){ | |
//avoid contextify's js wrapper | |
var contextifyPath = require('path').resolve(require.resolve('contextify'), '..', '..'); | |
var contextify = require('bindings')({ | |
module_root: contextifyPath, | |
bindings: 'contextify.node' | |
}); | |
// basic WeakMap shim if not available | |
var WM = typeof WeakMap !== 'undefined' ? WeakMap : function WeakMap(){ | |
var keys = [], values = []; | |
return { | |
set: function(key, val){ | |
keys.push(key); | |
values.push(val); | |
return val; | |
}, | |
get: function(key){ | |
var index = keys.indexOf(key); | |
if (~index) return values[index]; | |
}, | |
has: function(key){ | |
return !!~keys.indexOf(key); | |
}, | |
delete: function(key){ | |
var index = keys.indexOf(key); | |
if (~index) { | |
keys.splice(index, 1); | |
values.splice(index, 1); | |
return true; | |
} | |
return false; | |
} | |
}; | |
}; | |
// allow for proper garbage collection | |
var contexts = new WM; | |
var Context = contextify.ContextifyContext; | |
function createContext(sandbox){ | |
if (sandbox == null) { | |
sandbox = {}; | |
} else if (Object(sandbox) !== sandbox) { | |
throw new TypeError('Sandbox must be an object'); | |
} | |
contexts.set(sandbox, new Context(sandbox)); | |
return sandbox; | |
} | |
function runInContext(code, sandbox){ | |
if (Object(sandbox) === sandbox) { | |
if (!contexts.has(sandbox)) { | |
createContext(sandbox); | |
} | |
return contexts.get(sandbox).run(code); | |
} else { | |
throw new TypeError('Context must be an object'); | |
} | |
} | |
function runInThisContext(code){ | |
return runInContext(code, global); | |
} | |
function runInNewContext(code){ | |
var sandbox = createContext(); | |
var result = runInContext(code, sandbox); | |
dispose(sandbox); | |
return result; | |
} | |
function dispose(sandbox){ | |
contexts.delete(sandbox); | |
} | |
return { | |
createContext: createContext, | |
runInContext: runInContext, | |
runInThisContext: runInThisContext, | |
runInNewContext: runInNewContext, | |
dispose: dispose | |
}; | |
}(); | |
console.log('### setup'); | |
var sandbox = { test: 5 }; | |
var o = vm.createContext(sandbox); | |
console.log(o === sandbox); // true | |
console.log(o); | |
console.log(sandbox); | |
console.log('\n### no leaks'); | |
console.log(vm.runInContext('typeof run', o)); // undefined | |
console.log(vm.runInContext('typeof getGlobal', o)); // undefined | |
console.log('\n### dynamic updates'); | |
sandbox.thing = [555]; | |
console.log(vm.runInContext('thing', o)); // [555] | |
vm.runInContext('thing2 = { a: 666 }', o); | |
console.log(sandbox.thing2); // { a: 666 } | |
o.thing3 = '777'; | |
console.log(sandbox.thing3); // 777 | |
sandbox.thing4 = 888; | |
console.log(o.thing4) // 888 | |
o.thing5 = /999/; | |
console.log(vm.runInContext('thing5', o)) // /999/ | |
console.log('\n### compare'); | |
function getExternalGlobal () { return o } | |
function getLocalGlobal () { return vm.runInContext('this', o) } | |
o.getExternalGlobal = getExternalGlobal; | |
o.getLocalGlobal = getLocalGlobal; | |
o.externalGlobal = o; | |
o.localGlobal = vm.runInContext('this', o); | |
console.log(vm.runInContext("this === getExternalGlobal()", o)); // false | |
console.log(vm.runInContext("this === getLocalGlobal()", o)); // true | |
console.log(vm.runInContext("this === externalGlobal", o)); // false | |
console.log(vm.runInContext("this === localGlobal", o)); // true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment