Skip to content

Instantly share code, notes, and snippets.

@rehanift
Created April 29, 2012 21:23
Show Gist options
  • Save rehanift/2553335 to your computer and use it in GitHub Desktop.
Save rehanift/2553335 to your computer and use it in GitHub Desktop.
Using contextify to replace vm second version
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