Skip to content

Instantly share code, notes, and snippets.

@kumavis
Last active August 21, 2019 07:51
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 kumavis/afa64913d91780146abb0eb8a3056c35 to your computer and use it in GitHub Desktop.
Save kumavis/afa64913d91780146abb0eb8a3056c35 to your computer and use it in GitHub Desktop.
ses sloppyGlobals mini kernel
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 }
}
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