Last active
August 21, 2019 07:51
-
-
Save kumavis/afa64913d91780146abb0eb8a3056c35 to your computer and use it in GitHub Desktop.
ses sloppyGlobals mini kernel
This file contains hidden or 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
const test = require('tape-promise').default(require('tape')) | |
const SES = require('../lib/ses.umd.js') | |
const realm = SES.makeSESRootRealm() | |
test(async t => { | |
const globalStore = {} | |
runModuleA() | |
runModuleB() | |
function runModuleA () { | |
const code = ` | |
abc = true | |
` | |
const config = { | |
globals: { | |
'abc': 'write', | |
} | |
} | |
evaluateModule(code, config, globalStore) | |
} | |
function runModuleB () { | |
const code = ` | |
xyz = abc | |
` | |
const config = { | |
globals: { | |
'abc': 'read', | |
'xyz': 'write', | |
'process': 'read', | |
} | |
} | |
evaluateModule(code, config, globalStore) | |
} | |
}) | |
function evaluateModule (code, config, globalStore) { | |
const { globalsWriteProxy, globalsReadProxy } = createGlobalsProxies(globalStore, config) | |
realm.evaluate(code, globalsReadProxy, { sloppyGlobals: globalsWriteProxy }) | |
} | |
function createGlobalsProxies (globalStore, config) { | |
const globalsWriteProxy = new Proxy({}, { | |
// reads | |
has (_, key) { | |
console.log('globalWrite: has', key) | |
if (config.globals[key] !== 'write') return false | |
return key in globalStore | |
}, | |
ownKeys (_) { | |
console.log('globalWrite: ownKeys') | |
return Object.entries(config.globals) | |
.filter(([key, value]) => value === 'write') | |
.map(([key]) => key) | |
}, | |
get (_, key) { | |
console.log('globalWrite: get', key) | |
return globalStore[key] | |
}, | |
getOwnPropertyDescriptor (_, key) { | |
console.log('globalWrite: getOwnPropertyDescriptor', key) | |
return Reflect.getOwnPropertyDescriptor(globalStore, key) | |
}, | |
// writes | |
set (_, key, value) { | |
console.log('globalWrite: set', key) | |
if (config.globals[key] !== 'write') return false | |
globalStore[key] = value | |
return true | |
}, | |
defineProperty (_, key, propDescriptor) { | |
console.log('globalWrite: defineProperty', key, propDescriptor) | |
if (config.globals[key] !== 'write') return false | |
globalStore[key] = value | |
Reflect.defineProperty(globalStore, key, propDescriptor) | |
return true | |
}, | |
}) | |
const globalsReadProxy = new Proxy({}, { | |
// reads | |
has (_, key) { | |
console.log('globalRead: has', key) | |
if (!config.globals[key]) return false | |
return key in globalStore || key in global | |
}, | |
ownKeys (_) { | |
console.log('globalRead: ownKeys') | |
return Reflect.ownKeys(config.globals) | |
}, | |
get (_, key) { | |
console.log('globalRead: get', key) | |
if (!config.globals[key]) return undefined | |
return key in globalStore ? globalStore[key] : global[key] | |
}, | |
getOwnPropertyDescriptor (_, key) { | |
console.log('globalRead: getOwnPropertyDescriptor', key) | |
if (!config.globals[key]) return undefined | |
const propDescriptor = Reflect.getOwnPropertyDescriptor(globalStore, key) || | |
Reflect.getOwnPropertyDescriptor(global, key) | |
return propDescriptor | |
}, | |
// writes | |
set (_, key, value) { | |
console.log('globalRead: set', key, value) | |
return false | |
}, | |
defineProperty (_, key, propDescriptor) { | |
console.log('globalRead: defineProperty', key, propDescriptor) | |
return false | |
}, | |
}) | |
return { globalsWriteProxy, globalsReadProxy } | |
} |
This file contains hidden or 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
const test = require('tape-promise').default(require('tape')) | |
const SES = require('../lib/ses.umd.js') | |
const realm = SES.makeSESRootRealm() | |
test(async t => { | |
const globalStore = {} | |
runModuleA() | |
runModuleB() | |
function runModuleA () { | |
const code = ` | |
abc = true | |
` | |
const config = { | |
globals: { | |
'abc': 'write', | |
} | |
} | |
evaluateModule(code, config, globalStore) | |
} | |
function runModuleB () { | |
const code = ` | |
xyz = abc | |
process.env | |
` | |
const config = { | |
globals: { | |
'abc': 'read', | |
'xyz': 'write', | |
'process': 'read', | |
} | |
} | |
evaluateModule(code, config, globalStore) | |
} | |
}) | |
function evaluateModule (code, config, globalStore) { | |
const globalsProxy = createGlobalsProxies(globalStore, config) | |
realm.evaluate(code, {}, { sloppyGlobals: globalsProxy }) | |
} | |
function createGlobalsProxies (globalStore, config) { | |
const globalsProxy = new Proxy({}, { | |
// reads | |
has (_, key) { | |
console.log('globalWrite: has', key) | |
if (!(key in config.globals)) return false | |
return key in globalStore || key in global | |
}, | |
ownKeys (_) { | |
console.log('globalWrite: ownKeys') | |
return [...Reflect.ownKeys(config.globals), ...Reflect.ownKeys(global)] | |
}, | |
get (_, key) { | |
console.log('globalWrite: get', key) | |
if (!(key in config.globals)) return undefined | |
return key in globalStore ? globalStore[key] : global[key] | |
}, | |
getOwnPropertyDescriptor (_, key) { | |
if (!(key in config.globals)) return undefined | |
console.log('globalWrite: getOwnPropertyDescriptor', key) | |
return key in globalStore ? Reflect.getOwnPropertyDescriptor(globalStore, key) : Reflect.getOwnPropertyDescriptor(global, key) | |
}, | |
// writes | |
set (_, key, value) { | |
console.log('globalWrite: set', key) | |
if (config.globals[key] !== 'write') return false | |
globalStore[key] = value | |
return true | |
}, | |
defineProperty (_, key, propDescriptor) { | |
console.log('globalWrite: defineProperty', key, propDescriptor) | |
if (config.globals[key] !== 'write') return false | |
Reflect.defineProperty(globalStore, key, propDescriptor) | |
return true | |
}, | |
}) | |
return globalsProxy | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment