@nyariv/sandboxjs 0.8.23 → 0.8.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/.eslintignore +6 -0
  2. package/.eslintrc.js +22 -0
  3. package/.prettierrc +4 -0
  4. package/.vscode/settings.json +4 -0
  5. package/build/Sandbox.d.ts +11 -79
  6. package/build/Sandbox.js +21 -216
  7. package/build/SandboxExec.d.ts +25 -0
  8. package/build/SandboxExec.js +169 -0
  9. package/build/eval.d.ts +18 -0
  10. package/build/eval.js +43 -0
  11. package/build/executor.d.ts +29 -90
  12. package/build/executor.js +249 -328
  13. package/build/parser.d.ts +8 -239
  14. package/build/parser.js +342 -440
  15. package/build/unraw.js +13 -16
  16. package/build/utils.d.ts +242 -0
  17. package/build/utils.js +276 -0
  18. package/dist/Sandbox.d.ts +11 -79
  19. package/dist/Sandbox.js +106 -1
  20. package/dist/Sandbox.js.map +1 -1
  21. package/dist/Sandbox.min.js +2 -0
  22. package/dist/Sandbox.min.js.map +1 -0
  23. package/dist/SandboxExec.d.ts +25 -0
  24. package/dist/SandboxExec.js +173 -0
  25. package/dist/SandboxExec.js.map +1 -0
  26. package/dist/SandboxExec.min.js +2 -0
  27. package/dist/SandboxExec.min.js.map +1 -0
  28. package/dist/eval.d.ts +18 -0
  29. package/dist/executor.d.ts +29 -90
  30. package/dist/executor.js +1270 -0
  31. package/dist/executor.js.map +1 -0
  32. package/dist/node/Sandbox.d.ts +11 -79
  33. package/dist/node/Sandbox.js +36 -3150
  34. package/dist/node/SandboxExec.d.ts +25 -0
  35. package/dist/node/SandboxExec.js +176 -0
  36. package/dist/node/eval.d.ts +18 -0
  37. package/dist/node/executor.d.ts +29 -90
  38. package/dist/node/executor.js +1289 -0
  39. package/dist/node/parser.d.ts +8 -239
  40. package/dist/node/parser.js +1528 -0
  41. package/dist/node/utils.d.ts +242 -0
  42. package/dist/node/utils.js +290 -0
  43. package/dist/parser.d.ts +8 -239
  44. package/dist/parser.js +1514 -0
  45. package/dist/parser.js.map +1 -0
  46. package/dist/utils.d.ts +242 -0
  47. package/dist/utils.js +279 -0
  48. package/dist/utils.js.map +1 -0
  49. package/package.json +11 -3
  50. package/.github/workflows/npm-publish.yml +0 -34
  51. package/rollup.config.mjs +0 -33
package/build/executor.js CHANGED
@@ -1,4 +1,4 @@
1
- import { parse, lispifyFunction, CodeString, isLisp } from "./parser.js";
1
+ import { CodeString, isLisp, LocalScope, Prop, SandboxError, Scope, } from './utils.js';
2
2
  export class ExecReturn {
3
3
  constructor(auditReport, result, returned, breakLoop = false, continueLoop = false) {
4
4
  this.auditReport = auditReport;
@@ -8,154 +8,7 @@ export class ExecReturn {
8
8
  this.continueLoop = continueLoop;
9
9
  }
10
10
  }
11
- export class Prop {
12
- constructor(context, prop, isConst = false, isGlobal = false, isVariable = false) {
13
- this.context = context;
14
- this.prop = prop;
15
- this.isConst = isConst;
16
- this.isGlobal = isGlobal;
17
- this.isVariable = isVariable;
18
- }
19
- get(context) {
20
- if (this.context === undefined)
21
- throw new ReferenceError(`${this.prop} is not defined`);
22
- context.getSubscriptions.forEach((cb) => cb(this.context, this.prop));
23
- return this.context[this.prop];
24
- }
25
- }
26
11
  const optional = {};
27
- const reservedWords = new Set([
28
- 'instanceof',
29
- 'typeof',
30
- 'return',
31
- 'try',
32
- 'catch',
33
- 'if',
34
- 'finally',
35
- 'else',
36
- 'in',
37
- 'of',
38
- 'var',
39
- 'let',
40
- 'const',
41
- 'for',
42
- 'delete',
43
- 'false',
44
- 'true',
45
- 'while',
46
- 'do',
47
- 'break',
48
- 'continue',
49
- 'new',
50
- 'function',
51
- 'async',
52
- 'await',
53
- 'switch',
54
- 'case'
55
- ]);
56
- var VarType;
57
- (function (VarType) {
58
- VarType["let"] = "let";
59
- VarType["const"] = "const";
60
- VarType["var"] = "var";
61
- })(VarType || (VarType = {}));
62
- function keysOnly(obj) {
63
- const ret = Object.assign({}, obj);
64
- for (let key in ret) {
65
- ret[key] = true;
66
- }
67
- return ret;
68
- }
69
- export class Scope {
70
- constructor(parent, vars = {}, functionThis) {
71
- this.const = {};
72
- this.let = {};
73
- this.var = {};
74
- const isFuncScope = functionThis !== undefined || parent === null;
75
- this.parent = parent;
76
- this.allVars = vars;
77
- this.let = isFuncScope ? this.let : keysOnly(vars);
78
- this.var = isFuncScope ? keysOnly(vars) : this.var;
79
- this.globals = parent === null ? keysOnly(vars) : {};
80
- this.functionThis = functionThis;
81
- }
82
- get(key, functionScope = false) {
83
- if (key === 'this' && this.functionThis !== undefined) {
84
- return new Prop({ this: this.functionThis }, key, true, false, true);
85
- }
86
- if (reservedWords.has(key))
87
- throw new SyntaxError("Unexepected token '" + key + "'");
88
- if (this.parent === null || !functionScope || this.functionThis !== undefined) {
89
- if (this.globals.hasOwnProperty(key)) {
90
- return new Prop(this.functionThis, key, false, true, true);
91
- }
92
- if (key in this.allVars && (!(key in {}) || this.allVars.hasOwnProperty(key))) {
93
- return new Prop(this.allVars, key, this.const.hasOwnProperty(key), this.globals.hasOwnProperty(key), true);
94
- }
95
- if (this.parent === null) {
96
- return new Prop(undefined, key);
97
- }
98
- }
99
- return this.parent.get(key, functionScope);
100
- }
101
- set(key, val) {
102
- if (key === 'this')
103
- throw new SyntaxError('"this" cannot be assigned');
104
- if (reservedWords.has(key))
105
- throw new SyntaxError("Unexepected token '" + key + "'");
106
- let prop = this.get(key);
107
- if (prop.context === undefined) {
108
- throw new ReferenceError(`Variable '${key}' was not declared.`);
109
- }
110
- if (prop.isConst) {
111
- throw new TypeError(`Cannot assign to const variable '${key}'`);
112
- }
113
- if (prop.isGlobal) {
114
- throw new SandboxError(`Cannot override global variable '${key}'`);
115
- }
116
- prop.context[prop.prop] = val;
117
- return prop;
118
- }
119
- declare(key, type = null, value = undefined, isGlobal = false) {
120
- if (key === 'this')
121
- throw new SyntaxError('"this" cannot be declared');
122
- if (reservedWords.has(key))
123
- throw new SyntaxError("Unexepected token '" + key + "'");
124
- if (type === 'var' && this.functionThis === undefined && this.parent !== null) {
125
- return this.parent.declare(key, type, value, isGlobal);
126
- }
127
- else if ((this[type].hasOwnProperty(key) && type !== 'const' && !this.globals.hasOwnProperty(key)) || !(key in this.allVars)) {
128
- if (isGlobal) {
129
- this.globals[key] = true;
130
- }
131
- this[type][key] = true;
132
- this.allVars[key] = value;
133
- }
134
- else {
135
- throw new SandboxError(`Identifier '${key}' has already been declared`);
136
- }
137
- return new Prop(this.allVars, key, this.const.hasOwnProperty(key), isGlobal);
138
- }
139
- }
140
- export class FunctionScope {
141
- }
142
- export class LocalScope {
143
- }
144
- export class SandboxError extends Error {
145
- }
146
- let currentTicks;
147
- export function sandboxFunction(context, ticks) {
148
- return SandboxFunction;
149
- function SandboxFunction(...params) {
150
- let code = params.pop() || "";
151
- let parsed = parse(code);
152
- return createFunction(params, parsed.tree, ticks || currentTicks, {
153
- ...context,
154
- constants: parsed.constants,
155
- tree: parsed.tree
156
- }, undefined, 'anonymous');
157
- }
158
- }
159
12
  function generateArgs(argNames, args) {
160
13
  const vars = {};
161
14
  argNames.forEach((arg, i) => {
@@ -168,10 +21,10 @@ function generateArgs(argNames, args) {
168
21
  });
169
22
  return vars;
170
23
  }
171
- const sandboxedFunctions = new WeakSet();
24
+ export const sandboxedFunctions = new WeakSet();
172
25
  export function createFunction(argNames, parsed, ticks, context, scope, name) {
173
26
  if (context.ctx.options.forbidFunctionCreation) {
174
- throw new SandboxError("Function creation is forbidden");
27
+ throw new SandboxError('Function creation is forbidden');
175
28
  }
176
29
  let func;
177
30
  if (name === undefined) {
@@ -194,10 +47,10 @@ export function createFunction(argNames, parsed, ticks, context, scope, name) {
194
47
  }
195
48
  export function createFunctionAsync(argNames, parsed, ticks, context, scope, name) {
196
49
  if (context.ctx.options.forbidFunctionCreation) {
197
- throw new SandboxError("Function creation is forbidden");
50
+ throw new SandboxError('Function creation is forbidden');
198
51
  }
199
52
  if (!context.ctx.prototypeWhitelist?.has(Promise.prototype)) {
200
- throw new SandboxError("Async/await not permitted");
53
+ throw new SandboxError('Async/await not permitted');
201
54
  }
202
55
  let func;
203
56
  if (name === undefined) {
@@ -218,26 +71,6 @@ export function createFunctionAsync(argNames, parsed, ticks, context, scope, nam
218
71
  sandboxedFunctions.add(func);
219
72
  return func;
220
73
  }
221
- export function sandboxedEval(func) {
222
- return sandboxEval;
223
- function sandboxEval(code) {
224
- return func(code)();
225
- }
226
- }
227
- export function sandboxedSetTimeout(func) {
228
- return function sandboxSetTimeout(handler, ...args) {
229
- if (typeof handler !== 'string')
230
- return setTimeout(handler, ...args);
231
- return setTimeout(func(handler), ...args);
232
- };
233
- }
234
- export function sandboxedSetInterval(func) {
235
- return function sandboxSetInterval(handler, ...args) {
236
- if (typeof handler !== 'string')
237
- return setInterval(handler, ...args);
238
- return setInterval(func(handler), ...args);
239
- };
240
- }
241
74
  export function assignCheck(obj, context, op = 'assign') {
242
75
  if (obj.context === undefined) {
243
76
  throw new ReferenceError(`Cannot ${op} value to undefined.`);
@@ -251,26 +84,43 @@ export function assignCheck(obj, context, op = 'assign') {
251
84
  if (obj.isGlobal) {
252
85
  throw new SandboxError(`Cannot ${op} property '${obj.prop}' of a global object`);
253
86
  }
87
+ if (obj.context === null) {
88
+ throw new TypeError('Cannot set properties of null');
89
+ }
254
90
  if (typeof obj.context[obj.prop] === 'function' && !obj.context.hasOwnProperty(obj.prop)) {
255
91
  throw new SandboxError(`Override prototype property '${obj.prop}' not allowed`);
256
92
  }
257
- if (op === "delete") {
93
+ if (op === 'delete') {
258
94
  if (obj.context.hasOwnProperty(obj.prop)) {
259
- context.changeSubscriptions.get(obj.context)?.forEach((cb) => cb({ type: "delete", prop: obj.prop }));
260
- context.changeSubscriptionsGlobal.get(obj.context)?.forEach((cb) => cb({ type: "delete", prop: obj.prop }));
95
+ context.changeSubscriptions
96
+ .get(obj.context)
97
+ ?.forEach((cb) => cb({ type: 'delete', prop: obj.prop }));
98
+ context.changeSubscriptionsGlobal
99
+ .get(obj.context)
100
+ ?.forEach((cb) => cb({ type: 'delete', prop: obj.prop }));
261
101
  }
262
102
  }
263
103
  else if (obj.context.hasOwnProperty(obj.prop)) {
264
- context.setSubscriptions.get(obj.context)?.get(obj.prop)?.forEach((cb) => cb({
265
- type: "replace"
104
+ context.setSubscriptions
105
+ .get(obj.context)
106
+ ?.get(obj.prop)
107
+ ?.forEach((cb) => cb({
108
+ type: 'replace',
266
109
  }));
267
- context.setSubscriptionsGlobal.get(obj.context)?.get(obj.prop)?.forEach((cb) => cb({
268
- type: "replace"
110
+ context.setSubscriptionsGlobal
111
+ .get(obj.context)
112
+ ?.get(obj.prop)
113
+ ?.forEach((cb) => cb({
114
+ type: 'replace',
269
115
  }));
270
116
  }
271
117
  else {
272
- context.changeSubscriptions.get(obj.context)?.forEach((cb) => cb({ type: "create", prop: obj.prop }));
273
- context.changeSubscriptionsGlobal.get(obj.context)?.forEach((cb) => cb({ type: "create", prop: obj.prop }));
118
+ context.changeSubscriptions
119
+ .get(obj.context)
120
+ ?.forEach((cb) => cb({ type: 'create', prop: obj.prop }));
121
+ context.changeSubscriptionsGlobal
122
+ .get(obj.context)
123
+ ?.forEach((cb) => cb({ type: 'create', prop: obj.prop }));
274
124
  }
275
125
  }
276
126
  const arrayChange = new Set([
@@ -281,7 +131,7 @@ const arrayChange = new Set([
281
131
  [].splice,
282
132
  [].reverse,
283
133
  [].sort,
284
- [].copyWithin
134
+ [].copyWithin,
285
135
  ]);
286
136
  export class KeyVal {
287
137
  constructor(key, val) {
@@ -316,12 +166,14 @@ addOps(1 /* LispType.Prop */, (exec, done, ticks, a, b, obj, context, scope) =>
316
166
  }
317
167
  const type = typeof a;
318
168
  if (type === 'undefined' && obj === undefined) {
319
- let prop = scope.get(b);
169
+ const prop = scope.get(b);
320
170
  if (prop.context === context.ctx.sandboxGlobal) {
321
171
  if (context.ctx.options.audit) {
322
- context.ctx.auditReport.globalsAccess.add(b);
172
+ context.ctx.auditReport?.globalsAccess.add(b);
323
173
  }
324
- const rep = context.ctx.globalsWhitelist.has(context.ctx.sandboxGlobal[b]) ? context.evals.get(context.ctx.sandboxGlobal[b]) : undefined;
174
+ const rep = context.ctx.globalsWhitelist.has(context.ctx.sandboxGlobal[b])
175
+ ? context.evals.get(context.ctx.sandboxGlobal[b])
176
+ : undefined;
325
177
  if (rep) {
326
178
  done(undefined, rep);
327
179
  return;
@@ -353,39 +205,38 @@ addOps(1 /* LispType.Prop */, (exec, done, ticks, a, b, obj, context, scope) =>
353
205
  return;
354
206
  }
355
207
  const isFunction = type === 'function';
356
- let prototypeAccess = isFunction || !(a.hasOwnProperty(b) || typeof b === 'number');
208
+ const prototypeAccess = isFunction || !(a.hasOwnProperty(b) || typeof b === 'number');
357
209
  if (context.ctx.options.audit && prototypeAccess) {
358
210
  if (typeof b === 'string') {
359
211
  let prot = Object.getPrototypeOf(a);
360
212
  do {
361
213
  if (prot.hasOwnProperty(b)) {
362
- if (!context.ctx.auditReport.prototypeAccess[prot.constructor.name]) {
214
+ if (context.ctx.auditReport &&
215
+ !context.ctx.auditReport.prototypeAccess[prot.constructor.name]) {
363
216
  context.ctx.auditReport.prototypeAccess[prot.constructor.name] = new Set();
364
217
  }
365
- context.ctx.auditReport.prototypeAccess[prot.constructor.name].add(b);
218
+ context.ctx.auditReport?.prototypeAccess[prot.constructor.name].add(b);
366
219
  }
367
- } while (prot = Object.getPrototypeOf(prot));
220
+ } while ((prot = Object.getPrototypeOf(prot)));
368
221
  }
369
222
  }
370
223
  if (prototypeAccess) {
371
224
  if (isFunction) {
372
- if (!['name', 'length', 'constructor'].includes(b) && a.hasOwnProperty(b)) {
225
+ if (!['name', 'length', 'constructor'].includes(b) && (a.hasOwnProperty(b) || b === '__proto__')) {
373
226
  const whitelist = context.ctx.prototypeWhitelist.get(a.prototype);
374
227
  const replace = context.ctx.options.prototypeReplacements.get(a);
375
228
  if (replace) {
376
229
  done(undefined, new Prop(replace(a, true), b));
377
230
  return;
378
231
  }
379
- if (whitelist && (!whitelist.size || whitelist.has(b))) {
380
- }
381
- else {
232
+ if (!(whitelist && (!whitelist.size || whitelist.has(b)))) {
382
233
  throw new SandboxError(`Static method or property access not permitted: ${a.name}.${b}`);
383
234
  }
384
235
  }
385
236
  }
386
237
  else if (b !== 'constructor') {
387
238
  let prot = a;
388
- while (prot = Object.getPrototypeOf(prot)) {
239
+ while ((prot = Object.getPrototypeOf(prot))) {
389
240
  if (prot.hasOwnProperty(b)) {
390
241
  const whitelist = context.ctx.prototypeWhitelist.get(prot);
391
242
  const replace = context.ctx.options.prototypeReplacements.get(prot.constuctor);
@@ -399,7 +250,6 @@ addOps(1 /* LispType.Prop */, (exec, done, ticks, a, b, obj, context, scope) =>
399
250
  throw new SandboxError(`Method or property access not permitted: ${prot.constructor.name}.${b}`);
400
251
  }
401
252
  }
402
- ;
403
253
  }
404
254
  }
405
255
  if (context.evals.has(a[b])) {
@@ -410,23 +260,28 @@ addOps(1 /* LispType.Prop */, (exec, done, ticks, a, b, obj, context, scope) =>
410
260
  done(undefined, context.ctx.globalScope.get('this'));
411
261
  return;
412
262
  }
413
- let g = obj.isGlobal || (isFunction && !sandboxedFunctions.has(a)) || context.ctx.globalsWhitelist.has(a);
263
+ const g = obj.isGlobal ||
264
+ (isFunction && !sandboxedFunctions.has(a)) ||
265
+ context.ctx.globalsWhitelist.has(a);
414
266
  done(undefined, new Prop(a, b, false, g));
415
267
  });
416
- addOps(5 /* LispType.Call */, (exec, done, ticks, a, b, obj, context, scope) => {
268
+ addOps(5 /* LispType.Call */, (exec, done, ticks, a, b, obj, context) => {
417
269
  if (context.ctx.options.forbidFunctionCalls)
418
- throw new SandboxError("Function invocations are not allowed");
270
+ throw new SandboxError('Function invocations are not allowed');
419
271
  if (typeof a !== 'function') {
420
272
  throw new TypeError(`${typeof obj.prop === 'symbol' ? 'Symbol' : obj.prop} is not a function`);
421
273
  }
422
- const vals = b.map((item) => {
274
+ const vals = b
275
+ .map((item) => {
423
276
  if (item instanceof SpreadArray) {
424
277
  return [...item.item];
425
278
  }
426
279
  else {
427
280
  return [item];
428
281
  }
429
- }).flat().map((item) => valueOrProp(item, context));
282
+ })
283
+ .flat()
284
+ .map((item) => valueOrProp(item, context));
430
285
  if (typeof obj === 'function') {
431
286
  done(undefined, obj(...vals));
432
287
  return;
@@ -437,66 +292,71 @@ addOps(5 /* LispType.Call */, (exec, done, ticks, a, b, obj, context, scope) =>
437
292
  if (!x || !(typeof x === 'object') || cache.has(x))
438
293
  return;
439
294
  cache.add(x);
440
- for (let y in x) {
295
+ for (const y of Object.keys(x)) {
441
296
  context.getSubscriptions.forEach((cb) => cb(x, y));
442
297
  recurse(x[y]);
443
298
  }
444
299
  };
445
300
  recurse(vals[0]);
446
301
  }
447
- if (obj.context instanceof Array && arrayChange.has(obj.context[obj.prop]) && (context.changeSubscriptions.get(obj.context) || context.changeSubscriptionsGlobal.get(obj.context))) {
302
+ if (obj.context instanceof Array &&
303
+ arrayChange.has(obj.context[obj.prop]) &&
304
+ (context.changeSubscriptions.get(obj.context) ||
305
+ context.changeSubscriptionsGlobal.get(obj.context))) {
448
306
  let change;
449
307
  let changed = false;
450
- if (obj.prop === "push") {
308
+ if (obj.prop === 'push') {
451
309
  change = {
452
- type: "push",
453
- added: vals
310
+ type: 'push',
311
+ added: vals,
454
312
  };
455
313
  changed = !!vals.length;
456
314
  }
457
- else if (obj.prop === "pop") {
315
+ else if (obj.prop === 'pop') {
458
316
  change = {
459
- type: "pop",
460
- removed: obj.context.slice(-1)
317
+ type: 'pop',
318
+ removed: obj.context.slice(-1),
461
319
  };
462
320
  changed = !!change.removed.length;
463
321
  }
464
- else if (obj.prop === "shift") {
322
+ else if (obj.prop === 'shift') {
465
323
  change = {
466
- type: "shift",
467
- removed: obj.context.slice(0, 1)
324
+ type: 'shift',
325
+ removed: obj.context.slice(0, 1),
468
326
  };
469
327
  changed = !!change.removed.length;
470
328
  }
471
- else if (obj.prop === "unshift") {
329
+ else if (obj.prop === 'unshift') {
472
330
  change = {
473
- type: "unshift",
474
- added: vals
331
+ type: 'unshift',
332
+ added: vals,
475
333
  };
476
334
  changed = !!vals.length;
477
335
  }
478
- else if (obj.prop === "splice") {
336
+ else if (obj.prop === 'splice') {
479
337
  change = {
480
- type: "splice",
338
+ type: 'splice',
481
339
  startIndex: vals[0],
482
340
  deleteCount: vals[1] === undefined ? obj.context.length : vals[1],
483
341
  added: vals.slice(2),
484
- removed: obj.context.slice(vals[0], vals[1] === undefined ? undefined : vals[0] + vals[1])
342
+ removed: obj.context.slice(vals[0], vals[1] === undefined ? undefined : vals[0] + vals[1]),
485
343
  };
486
344
  changed = !!change.added.length || !!change.removed.length;
487
345
  }
488
- else if (obj.prop === "reverse" || obj.prop === "sort") {
346
+ else if (obj.prop === 'reverse' || obj.prop === 'sort') {
489
347
  change = { type: obj.prop };
490
348
  changed = !!obj.context.length;
491
349
  }
492
- else if (obj.prop === "copyWithin") {
493
- let len = vals[2] === undefined ? obj.context.length - vals[1] : Math.min(obj.context.length, vals[2] - vals[1]);
350
+ else if (obj.prop === 'copyWithin') {
351
+ const len = vals[2] === undefined
352
+ ? obj.context.length - vals[1]
353
+ : Math.min(obj.context.length, vals[2] - vals[1]);
494
354
  change = {
495
- type: "copyWithin",
355
+ type: 'copyWithin',
496
356
  startIndex: vals[0],
497
357
  endIndex: vals[0] + len,
498
358
  added: obj.context.slice(vals[1], vals[1] + len),
499
- removed: obj.context.slice(vals[0], vals[0] + len)
359
+ removed: obj.context.slice(vals[0], vals[0] + len),
500
360
  };
501
361
  changed = !!change.added.length || !!change.removed.length;
502
362
  }
@@ -508,9 +368,9 @@ addOps(5 /* LispType.Call */, (exec, done, ticks, a, b, obj, context, scope) =>
508
368
  obj.get(context);
509
369
  done(undefined, obj.context[obj.prop](...vals));
510
370
  });
511
- addOps(22 /* LispType.CreateObject */, (exec, done, ticks, a, b, obj, context, scope) => {
371
+ addOps(22 /* LispType.CreateObject */, (exec, done, ticks, a, b) => {
512
372
  let res = {};
513
- for (let item of b) {
373
+ for (const item of b) {
514
374
  if (item.key instanceof SpreadObject) {
515
375
  res = { ...res, ...item.key.item };
516
376
  }
@@ -521,26 +381,35 @@ addOps(22 /* LispType.CreateObject */, (exec, done, ticks, a, b, obj, context, s
521
381
  done(undefined, res);
522
382
  });
523
383
  addOps(6 /* LispType.KeyVal */, (exec, done, ticks, a, b) => done(undefined, new KeyVal(a, b)));
524
- addOps(12 /* LispType.CreateArray */, (exec, done, ticks, a, b, obj, context, scope) => {
525
- const items = b.map((item) => {
384
+ addOps(12 /* LispType.CreateArray */, (exec, done, ticks, a, b, obj, context) => {
385
+ const items = b
386
+ .map((item) => {
526
387
  if (item instanceof SpreadArray) {
527
388
  return [...item.item];
528
389
  }
529
390
  else {
530
391
  return [item];
531
392
  }
532
- }).flat().map((item) => valueOrProp(item, context));
393
+ })
394
+ .flat()
395
+ .map((item) => valueOrProp(item, context));
533
396
  done(undefined, items);
534
397
  });
535
398
  addOps(23 /* LispType.Group */, (exec, done, ticks, a, b) => done(undefined, b));
536
399
  addOps(35 /* LispType.GlobalSymbol */, (exec, done, ticks, a, b) => {
537
400
  switch (b) {
538
- case 'true': return done(undefined, true);
539
- case 'false': return done(undefined, false);
540
- case 'null': return done(undefined, null);
541
- case 'undefined': return done(undefined, undefined);
542
- case 'NaN': return done(undefined, NaN);
543
- case 'Infinity': return done(undefined, Infinity);
401
+ case 'true':
402
+ return done(undefined, true);
403
+ case 'false':
404
+ return done(undefined, false);
405
+ case 'null':
406
+ return done(undefined, null);
407
+ case 'undefined':
408
+ return done(undefined, undefined);
409
+ case 'NaN':
410
+ return done(undefined, NaN);
411
+ case 'Infinity':
412
+ return done(undefined, Infinity);
544
413
  }
545
414
  done(new Error('Unknown symbol: ' + b));
546
415
  });
@@ -550,19 +419,19 @@ addOps(2 /* LispType.StringIndex */, (exec, done, ticks, a, b, obj, context) =>
550
419
  addOps(85 /* LispType.RegexIndex */, (exec, done, ticks, a, b, obj, context) => {
551
420
  const reg = context.constants.regexes[parseInt(b)];
552
421
  if (!context.ctx.globalsWhitelist.has(RegExp)) {
553
- throw new SandboxError("Regex not permitted");
422
+ throw new SandboxError('Regex not permitted');
554
423
  }
555
424
  else {
556
425
  done(undefined, new RegExp(reg.regex, reg.flags));
557
426
  }
558
427
  });
559
428
  addOps(84 /* LispType.LiteralIndex */, (exec, done, ticks, a, b, obj, context, scope) => {
560
- let item = context.constants.literals[parseInt(b)];
429
+ const item = context.constants.literals[parseInt(b)];
561
430
  const [, name, js] = item;
562
- let found = [];
431
+ const found = [];
563
432
  let f;
564
- let resnums = [];
565
- while (f = literalRegex.exec(name)) {
433
+ const resnums = [];
434
+ while ((f = literalRegex.exec(name))) {
566
435
  if (!f[2]) {
567
436
  found.push(js[parseInt(f[3], 10)]);
568
437
  resnums.push(f[3]);
@@ -574,22 +443,22 @@ addOps(84 /* LispType.LiteralIndex */, (exec, done, ticks, a, b, obj, context, s
574
443
  done(err);
575
444
  return;
576
445
  }
577
- for (let i in resnums) {
446
+ for (const i of Object.keys(processed)) {
578
447
  const num = resnums[i];
579
448
  reses[num] = processed[i];
580
449
  }
581
450
  done(undefined, name.replace(/(\\\\)*(\\)?\${(\d+)}/g, (match, $$, $, num) => {
582
451
  if ($)
583
452
  return match;
584
- let res = reses[num];
453
+ const res = reses[num];
585
454
  return ($$ ? $$ : '') + `${valueOrProp(res, context)}`;
586
455
  }));
587
456
  });
588
457
  });
589
- addOps(18 /* LispType.SpreadArray */, (exec, done, ticks, a, b, obj, context, scope) => {
458
+ addOps(18 /* LispType.SpreadArray */, (exec, done, ticks, a, b) => {
590
459
  done(undefined, new SpreadArray(b));
591
460
  });
592
- addOps(17 /* LispType.SpreadObject */, (exec, done, ticks, a, b, obj, context, scope) => {
461
+ addOps(17 /* LispType.SpreadObject */, (exec, done, ticks, a, b) => {
593
462
  done(undefined, new SpreadObject(b));
594
463
  });
595
464
  addOps(24 /* LispType.Not */, (exec, done, ticks, a, b) => done(undefined, !b));
@@ -612,55 +481,55 @@ addOps(28 /* LispType.DecrementAfter */, (exec, done, ticks, a, b, obj, context)
612
481
  });
613
482
  addOps(9 /* LispType.Assign */, (exec, done, ticks, a, b, obj, context) => {
614
483
  assignCheck(obj, context);
615
- done(undefined, obj.context[obj.prop] = b);
484
+ done(undefined, (obj.context[obj.prop] = b));
616
485
  });
617
486
  addOps(66 /* LispType.AddEquals */, (exec, done, ticks, a, b, obj, context) => {
618
487
  assignCheck(obj, context);
619
- done(undefined, obj.context[obj.prop] += b);
488
+ done(undefined, (obj.context[obj.prop] += b));
620
489
  });
621
490
  addOps(65 /* LispType.SubractEquals */, (exec, done, ticks, a, b, obj, context) => {
622
491
  assignCheck(obj, context);
623
- done(undefined, obj.context[obj.prop] -= b);
492
+ done(undefined, (obj.context[obj.prop] -= b));
624
493
  });
625
494
  addOps(67 /* LispType.DivideEquals */, (exec, done, ticks, a, b, obj, context) => {
626
495
  assignCheck(obj, context);
627
- done(undefined, obj.context[obj.prop] /= b);
496
+ done(undefined, (obj.context[obj.prop] /= b));
628
497
  });
629
498
  addOps(69 /* LispType.MultiplyEquals */, (exec, done, ticks, a, b, obj, context) => {
630
499
  assignCheck(obj, context);
631
- done(undefined, obj.context[obj.prop] *= b);
500
+ done(undefined, (obj.context[obj.prop] *= b));
632
501
  });
633
502
  addOps(68 /* LispType.PowerEquals */, (exec, done, ticks, a, b, obj, context) => {
634
503
  assignCheck(obj, context);
635
- done(undefined, obj.context[obj.prop] **= b);
504
+ done(undefined, (obj.context[obj.prop] **= b));
636
505
  });
637
506
  addOps(70 /* LispType.ModulusEquals */, (exec, done, ticks, a, b, obj, context) => {
638
507
  assignCheck(obj, context);
639
- done(undefined, obj.context[obj.prop] %= b);
508
+ done(undefined, (obj.context[obj.prop] %= b));
640
509
  });
641
510
  addOps(71 /* LispType.BitNegateEquals */, (exec, done, ticks, a, b, obj, context) => {
642
511
  assignCheck(obj, context);
643
- done(undefined, obj.context[obj.prop] ^= b);
512
+ done(undefined, (obj.context[obj.prop] ^= b));
644
513
  });
645
514
  addOps(72 /* LispType.BitAndEquals */, (exec, done, ticks, a, b, obj, context) => {
646
515
  assignCheck(obj, context);
647
- done(undefined, obj.context[obj.prop] &= b);
516
+ done(undefined, (obj.context[obj.prop] &= b));
648
517
  });
649
518
  addOps(73 /* LispType.BitOrEquals */, (exec, done, ticks, a, b, obj, context) => {
650
519
  assignCheck(obj, context);
651
- done(undefined, obj.context[obj.prop] |= b);
520
+ done(undefined, (obj.context[obj.prop] |= b));
652
521
  });
653
522
  addOps(76 /* LispType.ShiftLeftEquals */, (exec, done, ticks, a, b, obj, context) => {
654
523
  assignCheck(obj, context);
655
- done(undefined, obj.context[obj.prop] <<= b);
524
+ done(undefined, (obj.context[obj.prop] <<= b));
656
525
  });
657
526
  addOps(75 /* LispType.ShiftRightEquals */, (exec, done, ticks, a, b, obj, context) => {
658
527
  assignCheck(obj, context);
659
- done(undefined, obj.context[obj.prop] >>= b);
528
+ done(undefined, (obj.context[obj.prop] >>= b));
660
529
  });
661
530
  addOps(74 /* LispType.UnsignedShiftRightEquals */, (exec, done, ticks, a, b, obj, context) => {
662
531
  assignCheck(obj, context);
663
- done(undefined, obj.context[obj.prop] >>= b);
532
+ done(undefined, (obj.context[obj.prop] >>= b));
664
533
  });
665
534
  addOps(57 /* LispType.LargerThan */, (exec, done, ticks, a, b) => done(undefined, a > b));
666
535
  addOps(56 /* LispType.SmallerThan */, (exec, done, ticks, a, b) => done(undefined, a < b));
@@ -702,22 +571,27 @@ addOps(61 /* LispType.Delete */, (exec, done, ticks, a, b, obj, context, scope,
702
571
  done(undefined, false);
703
572
  return;
704
573
  }
705
- done(undefined, delete bobj.context[bobj.prop]);
574
+ done(undefined, delete bobj.context?.[bobj.prop]);
706
575
  });
707
- addOps(8 /* LispType.Return */, (exec, done, ticks, a, b, obj, context) => done(undefined, b));
708
- addOps(34 /* LispType.Var */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
709
- done(undefined, scope.declare(a, VarType.var, b));
576
+ addOps(8 /* LispType.Return */, (exec, done, ticks, a, b) => done(undefined, b));
577
+ addOps(34 /* LispType.Var */, (exec, done, ticks, a, b, obj, context, scope) => {
578
+ done(undefined, scope.declare(a, "var" /* VarType.var */, b));
710
579
  });
711
580
  addOps(3 /* LispType.Let */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
712
- done(undefined, scope.declare(a, VarType.let, b, bobj && bobj.isGlobal));
581
+ done(undefined, scope.declare(a, "let" /* VarType.let */, b, bobj && bobj.isGlobal));
713
582
  });
714
- addOps(4 /* LispType.Const */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
715
- done(undefined, scope.declare(a, VarType.const, b));
583
+ addOps(4 /* LispType.Const */, (exec, done, ticks, a, b, obj, context, scope) => {
584
+ done(undefined, scope.declare(a, "const" /* VarType.const */, b));
716
585
  });
717
586
  addOps(11 /* LispType.ArrowFunction */, (exec, done, ticks, a, b, obj, context, scope) => {
718
587
  a = [...a];
719
- if (typeof obj[2] === "string" || obj[2] instanceof CodeString) {
720
- obj[2] = b = lispifyFunction(new CodeString(obj[2]), context.constants);
588
+ if (typeof obj[2] === 'string' || obj[2] instanceof CodeString) {
589
+ if (context.allowJit && context.evalContext) {
590
+ obj[2] = b = context.evalContext.lispifyFunction(new CodeString(obj[2]), context.constants);
591
+ }
592
+ else {
593
+ throw new SandboxError('Unevaluated code detected, JIT not allowed');
594
+ }
721
595
  }
722
596
  if (a.shift()) {
723
597
  done(undefined, createFunctionAsync(a, b, ticks, context, scope));
@@ -727,11 +601,16 @@ addOps(11 /* LispType.ArrowFunction */, (exec, done, ticks, a, b, obj, context,
727
601
  }
728
602
  });
729
603
  addOps(37 /* LispType.Function */, (exec, done, ticks, a, b, obj, context, scope) => {
730
- if (typeof obj[2] === "string" || obj[2] instanceof CodeString) {
731
- obj[2] = b = lispifyFunction(new CodeString(obj[2]), context.constants);
604
+ if (typeof obj[2] === 'string' || obj[2] instanceof CodeString) {
605
+ if (context.allowJit && context.evalContext) {
606
+ obj[2] = b = context.evalContext.lispifyFunction(new CodeString(obj[2]), context.constants);
607
+ }
608
+ else {
609
+ throw new SandboxError('Unevaluated code detected, JIT not allowed');
610
+ }
732
611
  }
733
- let isAsync = a.shift();
734
- let name = a.shift();
612
+ const isAsync = a.shift();
613
+ const name = a.shift();
735
614
  let func;
736
615
  if (isAsync === 88 /* LispType.True */) {
737
616
  func = createFunctionAsync(a, b, ticks, context, scope, name);
@@ -740,16 +619,21 @@ addOps(37 /* LispType.Function */, (exec, done, ticks, a, b, obj, context, scope
740
619
  func = createFunction(a, b, ticks, context, scope, name);
741
620
  }
742
621
  if (name) {
743
- scope.declare(name, VarType.var, func);
622
+ scope.declare(name, "var" /* VarType.var */, func);
744
623
  }
745
624
  done(undefined, func);
746
625
  });
747
626
  addOps(10 /* LispType.InlineFunction */, (exec, done, ticks, a, b, obj, context, scope) => {
748
- if (typeof obj[2] === "string" || obj[2] instanceof CodeString) {
749
- obj[2] = b = lispifyFunction(new CodeString(obj[2]), context.constants);
627
+ if (typeof obj[2] === 'string' || obj[2] instanceof CodeString) {
628
+ if (context.allowJit && context.evalContext) {
629
+ obj[2] = b = context.evalContext.lispifyFunction(new CodeString(obj[2]), context.constants);
630
+ }
631
+ else {
632
+ throw new SandboxError('Unevaluated code detected, JIT not allowed');
633
+ }
750
634
  }
751
- let isAsync = a.shift();
752
- let name = a.shift();
635
+ const isAsync = a.shift();
636
+ const name = a.shift();
753
637
  if (name) {
754
638
  scope = new Scope(scope, {});
755
639
  }
@@ -761,7 +645,7 @@ addOps(10 /* LispType.InlineFunction */, (exec, done, ticks, a, b, obj, context,
761
645
  func = createFunction(a, b, ticks, context, scope, name);
762
646
  }
763
647
  if (name) {
764
- scope.declare(name, VarType.let, func);
648
+ scope.declare(name, "let" /* VarType.let */, func);
765
649
  }
766
650
  done(undefined, func);
767
651
  });
@@ -769,23 +653,30 @@ addOps(38 /* LispType.Loop */, (exec, done, ticks, a, b, obj, context, scope) =>
769
653
  const [checkFirst, startInternal, getIterator, startStep, step, condition, beforeStep] = a;
770
654
  let loop = true;
771
655
  const loopScope = new Scope(scope, {});
772
- let internalVars = {
773
- '$$obj': undefined
656
+ const internalVars = {
657
+ $$obj: undefined,
774
658
  };
775
659
  const interalScope = new Scope(loopScope, internalVars);
776
660
  if (exec === execAsync) {
777
661
  (async () => {
778
662
  let ad;
779
663
  ad = asyncDone((d) => exec(ticks, startStep, loopScope, context, d));
780
- internalVars['$$obj'] = (ad = asyncDone((d) => exec(ticks, getIterator, loopScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
664
+ internalVars['$$obj'] =
665
+ (ad = asyncDone((d) => exec(ticks, getIterator, loopScope, context, d))).isInstant === true
666
+ ? ad.instant
667
+ : (await ad.p).result;
781
668
  ad = asyncDone((d) => exec(ticks, startInternal, interalScope, context, d));
782
669
  if (checkFirst)
783
- loop = (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
670
+ loop =
671
+ (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant ===
672
+ true
673
+ ? ad.instant
674
+ : (await ad.p).result;
784
675
  while (loop) {
785
- let innerLoopVars = {};
676
+ const innerLoopVars = {};
786
677
  ad = asyncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
787
678
  ad.isInstant === true ? ad.instant : (await ad.p).result;
788
- let res = await executeTreeAsync(ticks, context, b, [new Scope(loopScope, innerLoopVars)], "loop");
679
+ const res = await executeTreeAsync(ticks, context, b, [new Scope(loopScope, innerLoopVars)], 'loop');
789
680
  if (res instanceof ExecReturn && res.returned) {
790
681
  done(undefined, res);
791
682
  return;
@@ -794,7 +685,11 @@ addOps(38 /* LispType.Loop */, (exec, done, ticks, a, b, obj, context, scope) =>
794
685
  break;
795
686
  }
796
687
  ad = asyncDone((d) => exec(ticks, step, interalScope, context, d));
797
- loop = (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
688
+ loop =
689
+ (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant ===
690
+ true
691
+ ? ad.instant
692
+ : (await ad.p).result;
798
693
  }
799
694
  done();
800
695
  })().catch(done);
@@ -804,11 +699,11 @@ addOps(38 /* LispType.Loop */, (exec, done, ticks, a, b, obj, context, scope) =>
804
699
  internalVars['$$obj'] = syncDone((d) => exec(ticks, getIterator, loopScope, context, d)).result;
805
700
  syncDone((d) => exec(ticks, startInternal, interalScope, context, d));
806
701
  if (checkFirst)
807
- loop = (syncDone((d) => exec(ticks, condition, interalScope, context, d))).result;
702
+ loop = syncDone((d) => exec(ticks, condition, interalScope, context, d)).result;
808
703
  while (loop) {
809
- let innerLoopVars = {};
704
+ const innerLoopVars = {};
810
705
  syncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
811
- let res = executeTree(ticks, context, b, [new Scope(loopScope, innerLoopVars)], "loop");
706
+ const res = executeTree(ticks, context, b, [new Scope(loopScope, innerLoopVars)], 'loop');
812
707
  if (res instanceof ExecReturn && res.returned) {
813
708
  done(undefined, res);
814
709
  return;
@@ -817,18 +712,18 @@ addOps(38 /* LispType.Loop */, (exec, done, ticks, a, b, obj, context, scope) =>
817
712
  break;
818
713
  }
819
714
  syncDone((d) => exec(ticks, step, interalScope, context, d));
820
- loop = (syncDone((d) => exec(ticks, condition, interalScope, context, d))).result;
715
+ loop = syncDone((d) => exec(ticks, condition, interalScope, context, d)).result;
821
716
  }
822
717
  done();
823
718
  }
824
719
  });
825
720
  addOps(86 /* LispType.LoopAction */, (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
826
- if ((inLoopOrSwitch === "switch" && a === "continue") || !inLoopOrSwitch) {
827
- throw new SandboxError("Illegal " + a + " statement");
721
+ if ((inLoopOrSwitch === 'switch' && a === 'continue') || !inLoopOrSwitch) {
722
+ throw new SandboxError('Illegal ' + a + ' statement');
828
723
  }
829
- done(undefined, new ExecReturn(context.ctx.auditReport, undefined, false, a === "break", a === "continue"));
724
+ done(undefined, new ExecReturn(context.ctx.auditReport, undefined, false, a === 'break', a === 'continue'));
830
725
  });
831
- addOps(13 /* LispType.If */, (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
726
+ addOps(13 /* LispType.If */, (exec, done, ticks, a, b, obj, context, scope) => {
832
727
  exec(ticks, valueOrProp(a, context) ? b.t : b.f, scope, context, done);
833
728
  });
834
729
  addOps(15 /* LispType.InlineIf */, (exec, done, ticks, a, b, obj, context, scope) => {
@@ -846,18 +741,23 @@ addOps(40 /* LispType.Switch */, (exec, done, ticks, a, b, obj, context, scope)
846
741
  if (exec === execSync) {
847
742
  let res;
848
743
  let isTrue = false;
849
- for (let caseItem of b) {
850
- if (isTrue || (isTrue = !caseItem[1] || toTest === valueOrProp((syncDone((d) => exec(ticks, caseItem[1], scope, context, d))).result, context))) {
744
+ for (const caseItem of b) {
745
+ if (isTrue ||
746
+ (isTrue =
747
+ !caseItem[1] ||
748
+ toTest ===
749
+ valueOrProp(syncDone((d) => exec(ticks, caseItem[1], scope, context, d)).result, context))) {
851
750
  if (!caseItem[2])
852
751
  continue;
853
- res = executeTree(ticks, context, caseItem[2], [scope], "switch");
752
+ res = executeTree(ticks, context, caseItem[2], [scope], 'switch');
854
753
  if (res.breakLoop)
855
754
  break;
856
755
  if (res.returned) {
857
756
  done(undefined, res);
858
757
  return;
859
758
  }
860
- if (!caseItem[1]) { // default case
759
+ if (!caseItem[1]) {
760
+ // default case
861
761
  break;
862
762
  }
863
763
  }
@@ -868,19 +768,27 @@ addOps(40 /* LispType.Switch */, (exec, done, ticks, a, b, obj, context, scope)
868
768
  (async () => {
869
769
  let res;
870
770
  let isTrue = false;
871
- for (let caseItem of b) {
771
+ for (const caseItem of b) {
872
772
  let ad;
873
- if (isTrue || (isTrue = !caseItem[1] || toTest === valueOrProp((ad = asyncDone((d) => exec(ticks, caseItem[1], scope, context, d))).isInstant === true ? ad.instant : (await ad.p).result, context))) {
773
+ if (isTrue ||
774
+ (isTrue =
775
+ !caseItem[1] ||
776
+ toTest ===
777
+ valueOrProp((ad = asyncDone((d) => exec(ticks, caseItem[1], scope, context, d))).isInstant ===
778
+ true
779
+ ? ad.instant
780
+ : (await ad.p).result, context))) {
874
781
  if (!caseItem[2])
875
782
  continue;
876
- res = await executeTreeAsync(ticks, context, caseItem[2], [scope], "switch");
783
+ res = await executeTreeAsync(ticks, context, caseItem[2], [scope], 'switch');
877
784
  if (res.breakLoop)
878
785
  break;
879
786
  if (res.returned) {
880
787
  done(undefined, res);
881
788
  return;
882
789
  }
883
- if (!caseItem[1]) { // default case
790
+ if (!caseItem[1]) {
791
+ // default case
884
792
  break;
885
793
  }
886
794
  }
@@ -897,7 +805,7 @@ addOps(39 /* LispType.Try */, (exec, done, ticks, a, b, obj, context, scope, bob
897
805
  if (e)
898
806
  done(e);
899
807
  else if (err) {
900
- let sc = {};
808
+ const sc = {};
901
809
  if (exception)
902
810
  sc[exception] = err;
903
811
  executeTreeWithDone(exec, done, ticks, context, catchBody, [new Scope(scope)], inLoopOrSwitch);
@@ -908,16 +816,20 @@ addOps(39 /* LispType.Try */, (exec, done, ticks, a, b, obj, context, scope, bob
908
816
  }, ticks, context, finallyBody, [new Scope(scope, {})]);
909
817
  }, ticks, context, a, [new Scope(scope)], inLoopOrSwitch);
910
818
  });
911
- addOps(87 /* LispType.Void */, (exec, done, ticks, a) => { done(); });
819
+ addOps(87 /* LispType.Void */, (exec, done) => {
820
+ done();
821
+ });
912
822
  addOps(45 /* LispType.New */, (exec, done, ticks, a, b, obj, context) => {
913
823
  if (!context.ctx.globalsWhitelist.has(a) && !sandboxedFunctions.has(a)) {
914
824
  throw new SandboxError(`Object construction not allowed: ${a.constructor.name}`);
915
825
  }
916
826
  done(undefined, new a(...b));
917
827
  });
918
- addOps(46 /* LispType.Throw */, (exec, done, ticks, a, b) => { done(b); });
828
+ addOps(46 /* LispType.Throw */, (exec, done, ticks, a, b) => {
829
+ done(b);
830
+ });
919
831
  addOps(43 /* LispType.Expression */, (exec, done, ticks, a) => done(undefined, a.pop()));
920
- addOps(0 /* LispType.None */, (exec, done, ticks, a) => done());
832
+ addOps(0 /* LispType.None */, (exec, done) => done());
921
833
  function valueOrProp(a, context) {
922
834
  if (a instanceof Prop)
923
835
  return a.get(context);
@@ -934,7 +846,7 @@ export function execMany(ticks, exec, tree, done, scope, context, inLoopOrSwitch
934
846
  }
935
847
  }
936
848
  function _execManySync(ticks, tree, done, scope, context, inLoopOrSwitch) {
937
- let ret = [];
849
+ const ret = [];
938
850
  for (let i = 0; i < tree.length; i++) {
939
851
  let res;
940
852
  try {
@@ -957,12 +869,16 @@ function _execManySync(ticks, tree, done, scope, context, inLoopOrSwitch) {
957
869
  done(undefined, ret);
958
870
  }
959
871
  async function _execManyAsync(ticks, tree, done, scope, context, inLoopOrSwitch) {
960
- let ret = [];
872
+ const ret = [];
961
873
  for (let i = 0; i < tree.length; i++) {
962
874
  let res;
963
875
  try {
964
876
  let ad;
965
- res = (ad = asyncDone((d) => execAsync(ticks, tree[i], scope, context, d, inLoopOrSwitch))).isInstant === true ? ad.instant : (await ad.p).result;
877
+ res =
878
+ (ad = asyncDone((d) => execAsync(ticks, tree[i], scope, context, d, inLoopOrSwitch)))
879
+ .isInstant === true
880
+ ? ad.instant
881
+ : (await ad.p).result;
966
882
  }
967
883
  catch (e) {
968
884
  done(e);
@@ -992,13 +908,12 @@ export function asyncDone(callback) {
992
908
  instant = result;
993
909
  resolve({ result });
994
910
  }
995
- ;
996
911
  });
997
912
  });
998
913
  return {
999
914
  isInstant,
1000
915
  instant,
1001
- p
916
+ p,
1002
917
  };
1003
918
  }
1004
919
  export function syncDone(callback) {
@@ -1020,14 +935,16 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
1020
935
  resolve();
1021
936
  };
1022
937
  });
1023
- if (_execNoneRecurse(ticks, tree, scope, context, done, true, inLoopOrSwitch)) {
1024
- }
1025
- else if (isLisp(tree)) {
938
+ if (!_execNoneRecurse(ticks, tree, scope, context, done, true, inLoopOrSwitch) && isLisp(tree)) {
1026
939
  let op = tree[0];
1027
940
  let obj;
1028
941
  try {
1029
942
  let ad;
1030
- obj = (ad = asyncDone((d) => execAsync(ticks, tree[1], scope, context, d, inLoopOrSwitch))).isInstant === true ? ad.instant : (await ad.p).result;
943
+ obj =
944
+ (ad = asyncDone((d) => execAsync(ticks, tree[1], scope, context, d, inLoopOrSwitch)))
945
+ .isInstant === true
946
+ ? ad.instant
947
+ : (await ad.p).result;
1031
948
  }
1032
949
  catch (e) {
1033
950
  done(e);
@@ -1060,7 +977,11 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
1060
977
  let bobj;
1061
978
  try {
1062
979
  let ad;
1063
- bobj = (ad = asyncDone((d) => execAsync(ticks, tree[2], scope, context, d, inLoopOrSwitch))).isInstant === true ? ad.instant : (await ad.p).result;
980
+ bobj =
981
+ (ad = asyncDone((d) => execAsync(ticks, tree[2], scope, context, d, inLoopOrSwitch)))
982
+ .isInstant === true
983
+ ? ad.instant
984
+ : (await ad.p).result;
1064
985
  }
1065
986
  catch (e) {
1066
987
  done(e);
@@ -1079,7 +1000,7 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
1079
1000
  }
1080
1001
  if (ops.has(op)) {
1081
1002
  try {
1082
- ops.get(op)(execAsync, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch);
1003
+ ops.get(op)?.(execAsync, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch);
1083
1004
  }
1084
1005
  catch (err) {
1085
1006
  done(err);
@@ -1092,9 +1013,7 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
1092
1013
  await p;
1093
1014
  }
1094
1015
  export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
1095
- if (_execNoneRecurse(ticks, tree, scope, context, done, false, inLoopOrSwitch)) {
1096
- }
1097
- else if (isLisp(tree)) {
1016
+ if (!_execNoneRecurse(ticks, tree, scope, context, done, false, inLoopOrSwitch) && isLisp(tree)) {
1098
1017
  let op = tree[0];
1099
1018
  let obj;
1100
1019
  try {
@@ -1149,7 +1068,7 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
1149
1068
  }
1150
1069
  if (ops.has(op)) {
1151
1070
  try {
1152
- ops.get(op)(execSync, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch);
1071
+ ops.get(op)?.(execSync, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch);
1153
1072
  }
1154
1073
  catch (err) {
1155
1074
  done(err);
@@ -1169,20 +1088,20 @@ const unexecTypes = new Set([
1169
1088
  40 /* LispType.Switch */,
1170
1089
  14 /* LispType.IfCase */,
1171
1090
  16 /* LispType.InlineIfCase */,
1172
- 60 /* LispType.Typeof */
1091
+ 60 /* LispType.Typeof */,
1173
1092
  ]);
1093
+ export const currentTicks = { current: { ticks: BigInt(0) } };
1174
1094
  function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSwitch) {
1175
1095
  const exec = isAsync ? execAsync : execSync;
1176
- if (context.ctx.options.executionQuota <= ticks.ticks) {
1177
- if (typeof context.ctx.options.onExecutionQuotaReached === 'function' && context.ctx.options.onExecutionQuotaReached(ticks, scope, context, tree)) {
1178
- }
1179
- else {
1180
- done(new SandboxError("Execution quota exceeded"));
1181
- return;
1096
+ if (context.ctx.options.executionQuota && context.ctx.options.executionQuota <= ticks.ticks) {
1097
+ if (!(typeof context.ctx.options.onExecutionQuotaReached === 'function' &&
1098
+ context.ctx.options.onExecutionQuotaReached(ticks, scope, context, tree))) {
1099
+ done(new SandboxError('Execution quota exceeded'));
1100
+ return true;
1182
1101
  }
1183
1102
  }
1184
1103
  ticks.ticks++;
1185
- currentTicks = ticks;
1104
+ currentTicks.current = ticks;
1186
1105
  if (tree instanceof Prop) {
1187
1106
  try {
1188
1107
  done(undefined, tree.get(context));
@@ -1231,7 +1150,7 @@ function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSw
1231
1150
  }
1232
1151
  else if (unexecTypes.has(tree[0])) {
1233
1152
  try {
1234
- ops.get(tree[0])(exec, done, ticks, tree[1], tree[2], tree, context, scope, undefined, inLoopOrSwitch);
1153
+ ops.get(tree[0])?.(exec, done, ticks, tree[1], tree[2], tree, context, scope, undefined, inLoopOrSwitch);
1235
1154
  }
1236
1155
  catch (err) {
1237
1156
  done(err);
@@ -1247,7 +1166,9 @@ export function executeTree(ticks, context, executionTree, scopes = [], inLoopOr
1247
1166
  }
1248
1167
  export async function executeTreeAsync(ticks, context, executionTree, scopes = [], inLoopOrSwitch) {
1249
1168
  let ad;
1250
- return (ad = asyncDone((done) => executeTreeWithDone(execAsync, done, ticks, context, executionTree, scopes, inLoopOrSwitch))).isInstant === true ? ad.instant : (await ad.p).result;
1169
+ return (ad = asyncDone((done) => executeTreeWithDone(execAsync, done, ticks, context, executionTree, scopes, inLoopOrSwitch))).isInstant === true
1170
+ ? ad.instant
1171
+ : (await ad.p).result;
1251
1172
  }
1252
1173
  function executeTreeWithDone(exec, done, ticks, context, executionTree, scopes = [], inLoopOrSwitch) {
1253
1174
  if (!executionTree) {
@@ -1259,8 +1180,8 @@ function executeTreeWithDone(exec, done, ticks, context, executionTree, scopes =
1259
1180
  }
1260
1181
  let scope = context.ctx.globalScope;
1261
1182
  let s;
1262
- while (s = scopes.shift()) {
1263
- if (typeof s !== "object")
1183
+ while ((s = scopes.shift())) {
1184
+ if (typeof s !== 'object')
1264
1185
  continue;
1265
1186
  if (s instanceof Scope) {
1266
1187
  scope = s;