Skip to content

Instantly share code, notes, and snippets.

@mk-pmb
Last active August 16, 2019 01:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mk-pmb/4a0e0c045b74206793c1b92a6b543f44 to your computer and use it in GitHub Desktop.
Save mk-pmb/4a0e0c045b74206793c1b92a6b543f44 to your computer and use it in GitHub Desktop.
// -*- coding: utf-8, tab-width: 2 -*-
const vm = require('vm');
function consLog(...args) { console.log(...args); }
const initSandbox = {
c: consLog,
i: 42,
f: null,
g: null,
};
const initCode = [
'i += 1;',
'console.log("init i:", i);',
'if (!f) { f = function f() { return i; } }',
'c("f() inside:", f && f());',
'c("g() inside:", g && g());',
].join('\n');
function makeSavedState() {
const sandbox = {};
const ctx = vm.createContext(initSandbox);
const script = new vm.Script(initCode);
script.runInContext(ctx)
// f() inside: 43
// g() inside: null
console.log('initSandbox:', initSandbox);
// { c: [Function: consLog], i: 43, f: [Function: f], g: null }
console.log('f() outside:', initSandbox.f()); // 43
const state = script.createCachedData();
const encoded = state.toString('base64');
return encoded;
}
const encodedState = makeSavedState();
console.log('got state:', encodedState); // twPew…
const loadCode = [
'console.log("loaded i:", i);',
].join('\n');
function resumeFromState() {
const state = Buffer.from(encodedState, 'base64');
const loadScript = new vm.Script(loadCode, { cachedData: state });
console.log('loadScript rejected?', loadScript.cachedDataRejected); // true
const emptyScript = new vm.Script('', { cachedData: state });
console.log('emptyScript rejected?', emptyScript.cachedDataRejected); // true
const initScript = new vm.Script(initCode, { cachedData: state });
console.log('initScript rejected?', initScript.cachedDataRejected); // true
const otherSandbox = {
c: consLog,
i: 23,
f: function hello() { return 'Hello World!'; },
g: initSandbox.f,
};
initScript.runInNewContext(otherSandbox);
// f() inside: Hello World!
// g() inside: 43
console.log('otherSandbox:', otherSandbox);
// { c: [Function: consLog], i: 24, f: [Function: hello], g: [Function: f] }
console.log('another f() outside says:', otherSandbox.f()); // Hello World!
}
resumeFromState();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment