Skip to content

Commit

Permalink
with statements WIP 1
Browse files Browse the repository at this point in the history
  • Loading branch information
overlookmotel committed Aug 29, 2023
1 parent 9cd2252 commit 254543b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
52 changes: 50 additions & 2 deletions lib/init/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
const getScopeId = require('./getScopeId.js'),
addEvalFunctionsToTracker = require('./eval.js'),
internal = require('../shared/internal.js'),
{tracker} = require('../shared/tracker.js'),
{COMMON_JS_MODULE} = require('../shared/constants.js');
{tracker, getIfTrackerIsActive} = require('../shared/tracker.js'),
{COMMON_JS_MODULE, INTERNAL_VAR_NAMES_PREFIX} = require('../shared/constants.js');

// Exports

Expand Down Expand Up @@ -43,11 +43,59 @@ module.exports = (filename, module, require, nextBlockId, prefixNum) => {
localTracker.nextBlockId = nextBlockId;
localTracker.prefixNum = prefixNum;
addEvalFunctionsToTracker(localTracker, filename);
addWrapWithFunctionToTracker(localTracker, prefixNum);

// Return tracker and `getScopeId` functions
return [localTracker, getScopeId];
};

function addWrapWithFunctionToTracker(localTracker, prefixNum) {
// `.wrapWith` wraps an object used as object of a `with ()` statement.
//
// Filter out any accesses to Livepack's internal vars, to prevent the `with` object
// obscuring access to them.
//
// There can be no valid accesses to Livepack's internal vars, otherwise they'd have
// been renamed to avoid clashes with any existing vars.
// Only exception is in `eval()`, where var names cannot be predicted in advance
// e.g. `with ({livepack_tracker: 1}) { eval('livepack_tracker = 2'); }`.
// This should set the property on the `with` object.
// However, this is a pre-existing problem with `eval()`, and can manifest without `with`,
// so not going to try to solve it here either.
// TODO: Try to solve this.
//
// Also always returns false from `has` trap if in a tracker call.
// This renders the `with` object transparent, so tracker can get values of variables
// outside of the `with () {}` block. e.g. `let f, x = 123; with ({x: 1}) { f = () => x; }`
// Tracker in `f` needs to be able to get the value of `x` in outer scope.
//
// Proxy an empty object, and forward operations to the `with` object,
// rather than proxying the `with` object directly, to avoid breaking Proxy `has` trap's invariant
// that cannot report a property as non-existent if it's non-configurable.
// e.g. `with (Object.freeze({livepack_tracker: 123})) { ... }`
const internalVarsPrefix = `${INTERNAL_VAR_NAMES_PREFIX}${prefixNum || ''}_`;
localTracker.wrapWith = withObj => new Proxy(Object.create(null), {
has(target, key) {
// Act as if object has no properties if tracker call is in process
if (getIfTrackerIsActive()) return false;
// Act as if properties named like Livepack's internal vars don't exist
if (key.startsWith(internalVarsPrefix)) return false;
// Forward to `with` object
return Reflect.has(withObj, key);
},
get(target, key) {
return Reflect.get(withObj, key, withObj);
},
set(target, key, value) {
return Reflect.set(withObj, key, value, withObj);
},
deleteProperty(target, key) {
return Reflect.deleteProperty(withObj, key);
}
// NB: These are the only traps which can be triggered
});
}

// Imports
// These imports are after export to avoid circular requires in Jest tests
const captureFunctions = require('./functions.js'),
Expand Down
9 changes: 9 additions & 0 deletions lib/shared/tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const trackerError = {},
module.exports = {
tracker,
activateTracker,
getIfTrackerIsActive,
getTrackerResult,
trackerError
};
Expand Down Expand Up @@ -50,6 +51,14 @@ function activateTracker() {
trackerIsActive = true;
}

/**
* Get if tracker call is in progress.
* @returns {boolean} - `true` if tracker call is in progress
*/
function getIfTrackerIsActive() {
return trackerIsActive;
}

/**
* Get tracker result.
* @returns {Object} - Tracker result. Object with properties:
Expand Down

0 comments on commit 254543b

Please sign in to comment.