@nyariv/sandboxjs 0.8.22 → 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 (50) 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 -78
  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 +56 -95
  12. package/build/executor.js +739 -815
  13. package/build/parser.d.ts +112 -74
  14. package/build/parser.js +504 -542
  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 -78
  19. package/dist/Sandbox.js +106 -1
  20. package/dist/Sandbox.js.map +1 -1
  21. package/dist/Sandbox.min.js +1 -1
  22. package/dist/Sandbox.min.js.map +1 -1
  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 +56 -95
  30. package/dist/executor.js +1270 -0
  31. package/dist/executor.js.map +1 -0
  32. package/dist/node/Sandbox.d.ts +11 -78
  33. package/dist/node/Sandbox.js +37 -3091
  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 +56 -95
  38. package/dist/node/executor.js +1289 -0
  39. package/dist/node/parser.d.ts +112 -74
  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 +112 -74
  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 +22 -14
  50. package/.github/workflows/npm-publish.yml +0 -34
package/build/executor.js CHANGED
@@ -1,4 +1,4 @@
1
- import { SpreadArray, KeyVal, SpreadObject, If, Lisp, toLispArray, parse, lispifyFunction, CodeString, lispArrayKey } 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) {
@@ -193,12 +46,11 @@ export function createFunction(argNames, parsed, ticks, context, scope, name) {
193
46
  return func;
194
47
  }
195
48
  export function createFunctionAsync(argNames, parsed, ticks, context, scope, name) {
196
- var _a;
197
49
  if (context.ctx.options.forbidFunctionCreation) {
198
- throw new SandboxError("Function creation is forbidden");
50
+ throw new SandboxError('Function creation is forbidden');
199
51
  }
200
- if (!((_a = context.ctx.prototypeWhitelist) === null || _a === void 0 ? void 0 : _a.has(Promise.prototype))) {
201
- throw new SandboxError("Async/await not permitted");
52
+ if (!context.ctx.prototypeWhitelist?.has(Promise.prototype)) {
53
+ throw new SandboxError('Async/await not permitted');
202
54
  }
203
55
  let func;
204
56
  if (name === undefined) {
@@ -219,28 +71,7 @@ export function createFunctionAsync(argNames, parsed, ticks, context, scope, nam
219
71
  sandboxedFunctions.add(func);
220
72
  return func;
221
73
  }
222
- export function sandboxedEval(func) {
223
- return sandboxEval;
224
- function sandboxEval(code) {
225
- return func(code)();
226
- }
227
- }
228
- export function sandboxedSetTimeout(func) {
229
- return function sandboxSetTimeout(handler, ...args) {
230
- if (typeof handler !== 'string')
231
- return setTimeout(handler, ...args);
232
- return setTimeout(func(handler), ...args);
233
- };
234
- }
235
- export function sandboxedSetInterval(func) {
236
- return function sandboxSetInterval(handler, ...args) {
237
- if (typeof handler !== 'string')
238
- return setInterval(handler, ...args);
239
- return setInterval(func(handler), ...args);
240
- };
241
- }
242
74
  export function assignCheck(obj, context, op = 'assign') {
243
- var _a, _b, _c, _d, _e, _f, _g, _h;
244
75
  if (obj.context === undefined) {
245
76
  throw new ReferenceError(`Cannot ${op} value to undefined.`);
246
77
  }
@@ -253,26 +84,43 @@ export function assignCheck(obj, context, op = 'assign') {
253
84
  if (obj.isGlobal) {
254
85
  throw new SandboxError(`Cannot ${op} property '${obj.prop}' of a global object`);
255
86
  }
87
+ if (obj.context === null) {
88
+ throw new TypeError('Cannot set properties of null');
89
+ }
256
90
  if (typeof obj.context[obj.prop] === 'function' && !obj.context.hasOwnProperty(obj.prop)) {
257
91
  throw new SandboxError(`Override prototype property '${obj.prop}' not allowed`);
258
92
  }
259
- if (op === "delete") {
93
+ if (op === 'delete') {
260
94
  if (obj.context.hasOwnProperty(obj.prop)) {
261
- (_a = context.changeSubscriptions.get(obj.context)) === null || _a === void 0 ? void 0 : _a.forEach((cb) => cb({ type: "delete", prop: obj.prop }));
262
- (_b = context.changeSubscriptionsGlobal.get(obj.context)) === null || _b === void 0 ? void 0 : _b.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 }));
263
101
  }
264
102
  }
265
103
  else if (obj.context.hasOwnProperty(obj.prop)) {
266
- (_d = (_c = context.setSubscriptions.get(obj.context)) === null || _c === void 0 ? void 0 : _c.get(obj.prop)) === null || _d === void 0 ? void 0 : _d.forEach((cb) => cb({
267
- type: "replace"
104
+ context.setSubscriptions
105
+ .get(obj.context)
106
+ ?.get(obj.prop)
107
+ ?.forEach((cb) => cb({
108
+ type: 'replace',
268
109
  }));
269
- (_f = (_e = context.setSubscriptionsGlobal.get(obj.context)) === null || _e === void 0 ? void 0 : _e.get(obj.prop)) === null || _f === void 0 ? void 0 : _f.forEach((cb) => cb({
270
- type: "replace"
110
+ context.setSubscriptionsGlobal
111
+ .get(obj.context)
112
+ ?.get(obj.prop)
113
+ ?.forEach((cb) => cb({
114
+ type: 'replace',
271
115
  }));
272
116
  }
273
117
  else {
274
- (_g = context.changeSubscriptions.get(obj.context)) === null || _g === void 0 ? void 0 : _g.forEach((cb) => cb({ type: "create", prop: obj.prop }));
275
- (_h = context.changeSubscriptionsGlobal.get(obj.context)) === null || _h === void 0 ? void 0 : _h.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 }));
276
124
  }
277
125
  }
278
126
  const arrayChange = new Set([
@@ -283,546 +131,552 @@ const arrayChange = new Set([
283
131
  [].splice,
284
132
  [].reverse,
285
133
  [].sort,
286
- [].copyWithin
134
+ [].copyWithin,
287
135
  ]);
136
+ export class KeyVal {
137
+ constructor(key, val) {
138
+ this.key = key;
139
+ this.val = val;
140
+ }
141
+ }
142
+ export class SpreadObject {
143
+ constructor(item) {
144
+ this.item = item;
145
+ }
146
+ }
147
+ export class SpreadArray {
148
+ constructor(item) {
149
+ this.item = item;
150
+ }
151
+ }
152
+ export class If {
153
+ constructor(t, f) {
154
+ this.t = t;
155
+ this.f = f;
156
+ }
157
+ }
288
158
  const literalRegex = /(\$\$)*(\$)?\${(\d+)}/g;
289
- let ops2 = {
290
- 'prop': (exec, done, ticks, a, b, obj, context, scope) => {
291
- if (a === null) {
292
- throw new TypeError(`Cannot get property ${b} of null`);
293
- }
294
- const type = typeof a;
295
- if (type === 'undefined' && obj === undefined) {
296
- let prop = scope.get(b);
297
- if (prop.context === context.ctx.sandboxGlobal) {
298
- if (context.ctx.options.audit) {
299
- context.ctx.auditReport.globalsAccess.add(b);
300
- }
301
- const rep = context.ctx.globalsWhitelist.has(context.ctx.sandboxGlobal[b]) ? context.evals.get(context.ctx.sandboxGlobal[b]) : undefined;
302
- if (rep) {
303
- done(undefined, rep);
304
- return;
305
- }
159
+ export const ops = new Map();
160
+ export function addOps(type, cb) {
161
+ ops.set(type, cb);
162
+ }
163
+ addOps(1 /* LispType.Prop */, (exec, done, ticks, a, b, obj, context, scope) => {
164
+ if (a === null) {
165
+ throw new TypeError(`Cannot get property ${b} of null`);
166
+ }
167
+ const type = typeof a;
168
+ if (type === 'undefined' && obj === undefined) {
169
+ const prop = scope.get(b);
170
+ if (prop.context === context.ctx.sandboxGlobal) {
171
+ if (context.ctx.options.audit) {
172
+ context.ctx.auditReport?.globalsAccess.add(b);
306
173
  }
307
- if (prop.context && prop.context[b] === globalThis) {
308
- done(undefined, context.ctx.globalScope.get('this'));
174
+ const rep = context.ctx.globalsWhitelist.has(context.ctx.sandboxGlobal[b])
175
+ ? context.evals.get(context.ctx.sandboxGlobal[b])
176
+ : undefined;
177
+ if (rep) {
178
+ done(undefined, rep);
309
179
  return;
310
180
  }
311
- done(undefined, prop);
181
+ }
182
+ if (prop.context && prop.context[b] === globalThis) {
183
+ done(undefined, context.ctx.globalScope.get('this'));
312
184
  return;
313
185
  }
314
- else if (a === undefined) {
315
- throw new SandboxError("Cannot get property '" + b + "' of undefined");
186
+ done(undefined, prop);
187
+ return;
188
+ }
189
+ else if (a === undefined) {
190
+ throw new SandboxError("Cannot get property '" + b + "' of undefined");
191
+ }
192
+ if (type !== 'object') {
193
+ if (type === 'number') {
194
+ a = new Number(a);
316
195
  }
317
- if (type !== 'object') {
318
- if (type === 'number') {
319
- a = new Number(a);
320
- }
321
- else if (type === 'string') {
322
- a = new String(a);
323
- }
324
- else if (type === 'boolean') {
325
- a = new Boolean(a);
326
- }
196
+ else if (type === 'string') {
197
+ a = new String(a);
327
198
  }
328
- else if (typeof a.hasOwnProperty === 'undefined') {
329
- done(undefined, new Prop(undefined, b));
330
- return;
199
+ else if (type === 'boolean') {
200
+ a = new Boolean(a);
331
201
  }
332
- const isFunction = type === 'function';
333
- let prototypeAccess = isFunction || !(a.hasOwnProperty(b) || typeof b === 'number');
334
- if (context.ctx.options.audit && prototypeAccess) {
335
- if (typeof b === 'string') {
336
- let prot = Object.getPrototypeOf(a);
337
- do {
338
- if (prot.hasOwnProperty(b)) {
339
- if (!context.ctx.auditReport.prototypeAccess[prot.constructor.name]) {
340
- context.ctx.auditReport.prototypeAccess[prot.constructor.name] = new Set();
341
- }
342
- context.ctx.auditReport.prototypeAccess[prot.constructor.name].add(b);
202
+ }
203
+ else if (typeof a.hasOwnProperty === 'undefined') {
204
+ done(undefined, new Prop(undefined, b));
205
+ return;
206
+ }
207
+ const isFunction = type === 'function';
208
+ const prototypeAccess = isFunction || !(a.hasOwnProperty(b) || typeof b === 'number');
209
+ if (context.ctx.options.audit && prototypeAccess) {
210
+ if (typeof b === 'string') {
211
+ let prot = Object.getPrototypeOf(a);
212
+ do {
213
+ if (prot.hasOwnProperty(b)) {
214
+ if (context.ctx.auditReport &&
215
+ !context.ctx.auditReport.prototypeAccess[prot.constructor.name]) {
216
+ context.ctx.auditReport.prototypeAccess[prot.constructor.name] = new Set();
343
217
  }
344
- } while (prot = Object.getPrototypeOf(prot));
218
+ context.ctx.auditReport?.prototypeAccess[prot.constructor.name].add(b);
219
+ }
220
+ } while ((prot = Object.getPrototypeOf(prot)));
221
+ }
222
+ }
223
+ if (prototypeAccess) {
224
+ if (isFunction) {
225
+ if (!['name', 'length', 'constructor'].includes(b) && (a.hasOwnProperty(b) || b === '__proto__')) {
226
+ const whitelist = context.ctx.prototypeWhitelist.get(a.prototype);
227
+ const replace = context.ctx.options.prototypeReplacements.get(a);
228
+ if (replace) {
229
+ done(undefined, new Prop(replace(a, true), b));
230
+ return;
231
+ }
232
+ if (!(whitelist && (!whitelist.size || whitelist.has(b)))) {
233
+ throw new SandboxError(`Static method or property access not permitted: ${a.name}.${b}`);
234
+ }
345
235
  }
346
236
  }
347
- if (prototypeAccess) {
348
- if (isFunction) {
349
- if (!['name', 'length', 'constructor'].includes(b) && a.hasOwnProperty(b)) {
350
- const whitelist = context.ctx.prototypeWhitelist.get(a.prototype);
351
- const replace = context.ctx.options.prototypeReplacements.get(a);
237
+ else if (b !== 'constructor') {
238
+ let prot = a;
239
+ while ((prot = Object.getPrototypeOf(prot))) {
240
+ if (prot.hasOwnProperty(b)) {
241
+ const whitelist = context.ctx.prototypeWhitelist.get(prot);
242
+ const replace = context.ctx.options.prototypeReplacements.get(prot.constuctor);
352
243
  if (replace) {
353
- done(undefined, new Prop(replace(a, true), b));
244
+ done(undefined, new Prop(replace(a, false), b));
354
245
  return;
355
246
  }
356
247
  if (whitelist && (!whitelist.size || whitelist.has(b))) {
248
+ break;
357
249
  }
358
- else {
359
- throw new SandboxError(`Static method or property access not permitted: ${a.name}.${b}`);
360
- }
361
- }
362
- }
363
- else if (b !== 'constructor') {
364
- let prot = a;
365
- while (prot = Object.getPrototypeOf(prot)) {
366
- if (prot.hasOwnProperty(b)) {
367
- const whitelist = context.ctx.prototypeWhitelist.get(prot);
368
- const replace = context.ctx.options.prototypeReplacements.get(prot.constuctor);
369
- if (replace) {
370
- done(undefined, new Prop(replace(a, false), b));
371
- return;
372
- }
373
- if (whitelist && (!whitelist.size || whitelist.has(b))) {
374
- break;
375
- }
376
- throw new SandboxError(`Method or property access not permitted: ${prot.constructor.name}.${b}`);
377
- }
250
+ throw new SandboxError(`Method or property access not permitted: ${prot.constructor.name}.${b}`);
378
251
  }
379
- ;
380
252
  }
381
253
  }
382
- if (context.evals.has(a[b])) {
383
- done(undefined, context.evals.get(a[b]));
384
- return;
254
+ }
255
+ if (context.evals.has(a[b])) {
256
+ done(undefined, context.evals.get(a[b]));
257
+ return;
258
+ }
259
+ if (a[b] === globalThis) {
260
+ done(undefined, context.ctx.globalScope.get('this'));
261
+ return;
262
+ }
263
+ const g = obj.isGlobal ||
264
+ (isFunction && !sandboxedFunctions.has(a)) ||
265
+ context.ctx.globalsWhitelist.has(a);
266
+ done(undefined, new Prop(a, b, false, g));
267
+ });
268
+ addOps(5 /* LispType.Call */, (exec, done, ticks, a, b, obj, context) => {
269
+ if (context.ctx.options.forbidFunctionCalls)
270
+ throw new SandboxError('Function invocations are not allowed');
271
+ if (typeof a !== 'function') {
272
+ throw new TypeError(`${typeof obj.prop === 'symbol' ? 'Symbol' : obj.prop} is not a function`);
273
+ }
274
+ const vals = b
275
+ .map((item) => {
276
+ if (item instanceof SpreadArray) {
277
+ return [...item.item];
385
278
  }
386
- if (a[b] === globalThis) {
387
- done(undefined, context.ctx.globalScope.get('this'));
388
- return;
279
+ else {
280
+ return [item];
389
281
  }
390
- let g = obj.isGlobal || (isFunction && !sandboxedFunctions.has(a)) || context.ctx.globalsWhitelist.has(a);
391
- done(undefined, new Prop(a, b, false, g));
392
- },
393
- 'call': (exec, done, ticks, a, b, obj, context, scope) => {
394
- if (context.ctx.options.forbidFunctionCalls)
395
- throw new SandboxError("Function invocations are not allowed");
396
- if (typeof a !== 'function') {
397
- throw new TypeError(`${obj.prop} is not a function`);
398
- }
399
- const args = b.map((item) => {
400
- if (item instanceof SpreadArray) {
401
- return [...item.item];
402
- }
403
- else {
404
- return [item];
405
- }
406
- }).flat();
407
- execMany(ticks, exec, toLispArray(args), (err, vals) => {
408
- var _a, _b;
409
- if (err) {
410
- done(err);
411
- return;
412
- }
413
- if (typeof obj === 'function') {
414
- done(undefined, obj(...vals));
282
+ })
283
+ .flat()
284
+ .map((item) => valueOrProp(item, context));
285
+ if (typeof obj === 'function') {
286
+ done(undefined, obj(...vals));
287
+ return;
288
+ }
289
+ if (obj.context[obj.prop] === JSON.stringify && context.getSubscriptions.size) {
290
+ const cache = new Set();
291
+ const recurse = (x) => {
292
+ if (!x || !(typeof x === 'object') || cache.has(x))
415
293
  return;
294
+ cache.add(x);
295
+ for (const y of Object.keys(x)) {
296
+ context.getSubscriptions.forEach((cb) => cb(x, y));
297
+ recurse(x[y]);
416
298
  }
417
- if (obj.context[obj.prop] === JSON.stringify && context.getSubscriptions.size) {
418
- const cache = new Set();
419
- const recurse = (x) => {
420
- if (!x || !(typeof x === 'object') || cache.has(x))
421
- return;
422
- cache.add(x);
423
- for (let y in x) {
424
- context.getSubscriptions.forEach((cb) => cb(x, y));
425
- recurse(x[y]);
426
- }
427
- };
428
- recurse(vals[0]);
429
- }
430
- if (obj.context instanceof Array && arrayChange.has(obj.context[obj.prop]) && (context.changeSubscriptions.get(obj.context) || context.changeSubscriptionsGlobal.get(obj.context))) {
431
- let change;
432
- let changed = false;
433
- if (obj.prop === "push") {
434
- change = {
435
- type: "push",
436
- added: vals
437
- };
438
- changed = !!vals.length;
439
- }
440
- else if (obj.prop === "pop") {
441
- change = {
442
- type: "pop",
443
- removed: obj.context.slice(-1)
444
- };
445
- changed = !!change.removed.length;
446
- }
447
- else if (obj.prop === "shift") {
448
- change = {
449
- type: "shift",
450
- removed: obj.context.slice(0, 1)
451
- };
452
- changed = !!change.removed.length;
453
- }
454
- else if (obj.prop === "unshift") {
455
- change = {
456
- type: "unshift",
457
- added: vals
458
- };
459
- changed = !!vals.length;
460
- }
461
- else if (obj.prop === "splice") {
462
- change = {
463
- type: "splice",
464
- startIndex: vals[0],
465
- deleteCount: vals[1] === undefined ? obj.context.length : vals[1],
466
- added: vals.slice(2),
467
- removed: obj.context.slice(vals[0], vals[1] === undefined ? undefined : vals[0] + vals[1])
468
- };
469
- changed = !!change.added.length || !!change.removed.length;
470
- }
471
- else if (obj.prop === "reverse" || obj.prop === "sort") {
472
- change = { type: obj.prop };
473
- changed = !!obj.context.length;
474
- }
475
- else if (obj.prop === "copyWithin") {
476
- let len = vals[2] === undefined ? obj.context.length - vals[1] : Math.min(obj.context.length, vals[2] - vals[1]);
477
- change = {
478
- type: "copyWithin",
479
- startIndex: vals[0],
480
- endIndex: vals[0] + len,
481
- added: obj.context.slice(vals[1], vals[1] + len),
482
- removed: obj.context.slice(vals[0], vals[0] + len)
483
- };
484
- changed = !!change.added.length || !!change.removed.length;
485
- }
486
- if (changed) {
487
- (_a = context.changeSubscriptions.get(obj.context)) === null || _a === void 0 ? void 0 : _a.forEach((cb) => cb(change));
488
- (_b = context.changeSubscriptionsGlobal.get(obj.context)) === null || _b === void 0 ? void 0 : _b.forEach((cb) => cb(change));
489
- }
490
- }
491
- obj.get(context);
492
- done(undefined, obj.context[obj.prop](...vals));
493
- }, scope, context);
494
- },
495
- 'createObject': (exec, done, ticks, a, b, obj, context, scope) => {
496
- let res = {};
497
- for (let item of b) {
498
- if (item instanceof SpreadObject) {
499
- res = { ...res, ...item.item };
500
- }
501
- else {
502
- res[item.key] = item.val;
503
- }
299
+ };
300
+ recurse(vals[0]);
301
+ }
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))) {
306
+ let change;
307
+ let changed = false;
308
+ if (obj.prop === 'push') {
309
+ change = {
310
+ type: 'push',
311
+ added: vals,
312
+ };
313
+ changed = !!vals.length;
314
+ }
315
+ else if (obj.prop === 'pop') {
316
+ change = {
317
+ type: 'pop',
318
+ removed: obj.context.slice(-1),
319
+ };
320
+ changed = !!change.removed.length;
321
+ }
322
+ else if (obj.prop === 'shift') {
323
+ change = {
324
+ type: 'shift',
325
+ removed: obj.context.slice(0, 1),
326
+ };
327
+ changed = !!change.removed.length;
328
+ }
329
+ else if (obj.prop === 'unshift') {
330
+ change = {
331
+ type: 'unshift',
332
+ added: vals,
333
+ };
334
+ changed = !!vals.length;
335
+ }
336
+ else if (obj.prop === 'splice') {
337
+ change = {
338
+ type: 'splice',
339
+ startIndex: vals[0],
340
+ deleteCount: vals[1] === undefined ? obj.context.length : vals[1],
341
+ added: vals.slice(2),
342
+ removed: obj.context.slice(vals[0], vals[1] === undefined ? undefined : vals[0] + vals[1]),
343
+ };
344
+ changed = !!change.added.length || !!change.removed.length;
345
+ }
346
+ else if (obj.prop === 'reverse' || obj.prop === 'sort') {
347
+ change = { type: obj.prop };
348
+ changed = !!obj.context.length;
349
+ }
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]);
354
+ change = {
355
+ type: 'copyWithin',
356
+ startIndex: vals[0],
357
+ endIndex: vals[0] + len,
358
+ added: obj.context.slice(vals[1], vals[1] + len),
359
+ removed: obj.context.slice(vals[0], vals[0] + len),
360
+ };
361
+ changed = !!change.added.length || !!change.removed.length;
362
+ }
363
+ if (changed) {
364
+ context.changeSubscriptions.get(obj.context)?.forEach((cb) => cb(change));
365
+ context.changeSubscriptionsGlobal.get(obj.context)?.forEach((cb) => cb(change));
504
366
  }
505
- done(undefined, res);
506
- },
507
- 'keyVal': (exec, done, ticks, a, b) => done(undefined, new KeyVal(a, b)),
508
- 'createArray': (exec, done, ticks, a, b, obj, context, scope) => {
509
- const items = b.map((item) => {
510
- if (item instanceof SpreadArray) {
511
- return [...item.item];
512
- }
513
- else {
514
- return [item];
515
- }
516
- }).flat();
517
- execMany(ticks, exec, toLispArray(items), done, scope, context);
518
- },
519
- 'group': (exec, done, ticks, a, b) => done(undefined, b),
520
- 'string': (exec, done, ticks, a, b, obj, context) => done(undefined, context.constants.strings[b]),
521
- 'regex': (exec, done, ticks, a, b, obj, context) => {
522
- const reg = context.constants.regexes[b];
523
- if (!context.ctx.globalsWhitelist.has(RegExp)) {
524
- throw new SandboxError("Regex not permitted");
367
+ }
368
+ obj.get(context);
369
+ done(undefined, obj.context[obj.prop](...vals));
370
+ });
371
+ addOps(22 /* LispType.CreateObject */, (exec, done, ticks, a, b) => {
372
+ let res = {};
373
+ for (const item of b) {
374
+ if (item.key instanceof SpreadObject) {
375
+ res = { ...res, ...item.key.item };
525
376
  }
526
377
  else {
527
- done(undefined, new RegExp(reg.regex, reg.flags));
528
- }
529
- },
530
- 'literal': (exec, done, ticks, a, b, obj, context, scope) => {
531
- let name = context.constants.literals[b].a;
532
- let found = toLispArray([]);
533
- let f;
534
- let resnums = [];
535
- while (f = literalRegex.exec(name)) {
536
- if (!f[2]) {
537
- found.push(context.constants.literals[b].b[parseInt(f[3], 10)]);
538
- resnums.push(f[3]);
539
- }
378
+ res[item.key] = item.val;
540
379
  }
541
- execMany(ticks, exec, found, (err, processed) => {
542
- const reses = {};
543
- if (err) {
544
- done(err);
545
- return;
546
- }
547
- for (let i in resnums) {
548
- const num = resnums[i];
549
- reses[num] = processed[i];
550
- }
551
- done(undefined, name.replace(/(\\\\)*(\\)?\${(\d+)}/g, (match, $$, $, num) => {
552
- if ($)
553
- return match;
554
- let res = reses[num];
555
- return ($$ ? $$ : '') + `${valueOrProp(res, context)}`;
556
- }));
557
- }, scope, context);
558
- },
559
- 'spreadArray': (exec, done, ticks, a, b, obj, context, scope) => {
560
- exec(ticks, b, scope, context, (err, res) => {
561
- if (err) {
562
- done(err);
563
- return;
564
- }
565
- done(undefined, new SpreadArray(res));
566
- });
567
- },
568
- 'spreadObject': (exec, done, ticks, a, b, obj, context, scope) => {
569
- exec(ticks, b, scope, context, (err, res) => {
570
- if (err) {
571
- done(err);
572
- return;
573
- }
574
- done(undefined, new SpreadObject(res));
575
- });
576
- },
577
- '!': (exec, done, ticks, a, b) => done(undefined, !b),
578
- '~': (exec, done, ticks, a, b) => done(undefined, ~b),
579
- '++$': (exec, done, ticks, a, b, obj, context) => {
580
- assignCheck(obj, context);
581
- done(undefined, ++obj.context[obj.prop]);
582
- },
583
- '$++': (exec, done, ticks, a, b, obj, context) => {
584
- assignCheck(obj, context);
585
- done(undefined, obj.context[obj.prop]++);
586
- },
587
- '--$': (exec, done, ticks, a, b, obj, context) => {
588
- assignCheck(obj, context);
589
- done(undefined, --obj.context[obj.prop]);
590
- },
591
- '$--': (exec, done, ticks, a, b, obj, context) => {
592
- assignCheck(obj, context);
593
- done(undefined, obj.context[obj.prop]--);
594
- },
595
- '=': (exec, done, ticks, a, b, obj, context) => {
596
- assignCheck(obj, context);
597
- done(undefined, obj.context[obj.prop] = b);
598
- },
599
- '+=': (exec, done, ticks, a, b, obj, context) => {
600
- assignCheck(obj, context);
601
- done(undefined, obj.context[obj.prop] += b);
602
- },
603
- '-=': (exec, done, ticks, a, b, obj, context) => {
604
- assignCheck(obj, context);
605
- done(undefined, obj.context[obj.prop] -= b);
606
- },
607
- '/=': (exec, done, ticks, a, b, obj, context) => {
608
- assignCheck(obj, context);
609
- done(undefined, obj.context[obj.prop] /= b);
610
- },
611
- '*=': (exec, done, ticks, a, b, obj, context) => {
612
- assignCheck(obj, context);
613
- done(undefined, obj.context[obj.prop] *= b);
614
- },
615
- '**=': (exec, done, ticks, a, b, obj, context) => {
616
- assignCheck(obj, context);
617
- done(undefined, obj.context[obj.prop] **= b);
618
- },
619
- '%=': (exec, done, ticks, a, b, obj, context) => {
620
- assignCheck(obj, context);
621
- done(undefined, obj.context[obj.prop] %= b);
622
- },
623
- '^=': (exec, done, ticks, a, b, obj, context) => {
624
- assignCheck(obj, context);
625
- done(undefined, obj.context[obj.prop] ^= b);
626
- },
627
- '&=': (exec, done, ticks, a, b, obj, context) => {
628
- assignCheck(obj, context);
629
- done(undefined, obj.context[obj.prop] &= b);
630
- },
631
- '|=': (exec, done, ticks, a, b, obj, context) => {
632
- assignCheck(obj, context);
633
- done(undefined, obj.context[obj.prop] |= b);
634
- },
635
- '<<=': (exec, done, ticks, a, b, obj, context) => {
636
- assignCheck(obj, context);
637
- done(undefined, obj.context[obj.prop] <<= b);
638
- },
639
- '>>=': (exec, done, ticks, a, b, obj, context) => {
640
- assignCheck(obj, context);
641
- done(undefined, obj.context[obj.prop] >>= b);
642
- },
643
- '>>>=': (exec, done, ticks, a, b, obj, context) => {
644
- assignCheck(obj, context);
645
- done(undefined, obj.context[obj.prop] >>= b);
646
- },
647
- '?': (exec, done, ticks, a, b, obj, context, scope) => {
648
- if (!(b instanceof If)) {
649
- throw new SyntaxError('Invalid inline if');
650
- }
651
- exec(ticks, a, scope, context, (err, res) => {
652
- if (err) {
653
- done(err);
654
- }
655
- else {
656
- exec(ticks, valueOrProp(res, context) ? b.t : b.f, scope, context, done);
657
- }
658
- });
659
- },
660
- '>': (exec, done, ticks, a, b) => done(undefined, a > b),
661
- '<': (exec, done, ticks, a, b) => done(undefined, a < b),
662
- '>=': (exec, done, ticks, a, b) => done(undefined, a >= b),
663
- '<=': (exec, done, ticks, a, b) => done(undefined, a <= b),
664
- '==': (exec, done, ticks, a, b) => done(undefined, a == b),
665
- '===': (exec, done, ticks, a, b) => done(undefined, a === b),
666
- '!=': (exec, done, ticks, a, b) => done(undefined, a != b),
667
- '!==': (exec, done, ticks, a, b) => done(undefined, a !== b),
668
- '&&': (exec, done, ticks, a, b) => done(undefined, a && b),
669
- '||': (exec, done, ticks, a, b) => done(undefined, a || b),
670
- '&': (exec, done, ticks, a, b) => done(undefined, a & b),
671
- '|': (exec, done, ticks, a, b) => done(undefined, a | b),
672
- ':': (exec, done, ticks, a, b) => done(undefined, new If(a, b)),
673
- '+': (exec, done, ticks, a, b) => done(undefined, a + b),
674
- '-': (exec, done, ticks, a, b) => done(undefined, a - b),
675
- '$+': (exec, done, ticks, a, b) => done(undefined, +b),
676
- '$-': (exec, done, ticks, a, b) => done(undefined, -b),
677
- '/': (exec, done, ticks, a, b) => done(undefined, a / b),
678
- '^': (exec, done, ticks, a, b) => done(undefined, a ^ b),
679
- '*': (exec, done, ticks, a, b) => done(undefined, a * b),
680
- '%': (exec, done, ticks, a, b) => done(undefined, a % b),
681
- '<<': (exec, done, ticks, a, b) => done(undefined, a << b),
682
- '>>': (exec, done, ticks, a, b) => done(undefined, a >> b),
683
- '>>>': (exec, done, ticks, a, b) => done(undefined, a >>> b),
684
- 'typeof': (exec, done, ticks, a, b, obj, context, scope) => {
685
- exec(ticks, b, scope, context, (e, prop) => {
686
- done(undefined, typeof valueOrProp(prop, context));
687
- });
688
- },
689
- 'instanceof': (exec, done, ticks, a, b) => done(undefined, a instanceof b),
690
- 'in': (exec, done, ticks, a, b) => done(undefined, a in b),
691
- 'delete': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
692
- if (bobj.context === undefined) {
693
- done(undefined, true);
694
- return;
380
+ }
381
+ done(undefined, res);
382
+ });
383
+ addOps(6 /* LispType.KeyVal */, (exec, done, ticks, a, b) => done(undefined, new KeyVal(a, b)));
384
+ addOps(12 /* LispType.CreateArray */, (exec, done, ticks, a, b, obj, context) => {
385
+ const items = b
386
+ .map((item) => {
387
+ if (item instanceof SpreadArray) {
388
+ return [...item.item];
389
+ }
390
+ else {
391
+ return [item];
392
+ }
393
+ })
394
+ .flat()
395
+ .map((item) => valueOrProp(item, context));
396
+ done(undefined, items);
397
+ });
398
+ addOps(23 /* LispType.Group */, (exec, done, ticks, a, b) => done(undefined, b));
399
+ addOps(35 /* LispType.GlobalSymbol */, (exec, done, ticks, a, b) => {
400
+ switch (b) {
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);
413
+ }
414
+ done(new Error('Unknown symbol: ' + b));
415
+ });
416
+ addOps(7 /* LispType.Number */, (exec, done, ticks, a, b) => done(undefined, Number(b)));
417
+ addOps(83 /* LispType.BigInt */, (exec, done, ticks, a, b) => done(undefined, BigInt(b)));
418
+ addOps(2 /* LispType.StringIndex */, (exec, done, ticks, a, b, obj, context) => done(undefined, context.constants.strings[parseInt(b)]));
419
+ addOps(85 /* LispType.RegexIndex */, (exec, done, ticks, a, b, obj, context) => {
420
+ const reg = context.constants.regexes[parseInt(b)];
421
+ if (!context.ctx.globalsWhitelist.has(RegExp)) {
422
+ throw new SandboxError('Regex not permitted');
423
+ }
424
+ else {
425
+ done(undefined, new RegExp(reg.regex, reg.flags));
426
+ }
427
+ });
428
+ addOps(84 /* LispType.LiteralIndex */, (exec, done, ticks, a, b, obj, context, scope) => {
429
+ const item = context.constants.literals[parseInt(b)];
430
+ const [, name, js] = item;
431
+ const found = [];
432
+ let f;
433
+ const resnums = [];
434
+ while ((f = literalRegex.exec(name))) {
435
+ if (!f[2]) {
436
+ found.push(js[parseInt(f[3], 10)]);
437
+ resnums.push(f[3]);
695
438
  }
696
- assignCheck(bobj, context, 'delete');
697
- if (bobj.isVariable) {
698
- done(undefined, false);
439
+ }
440
+ exec(ticks, found, scope, context, (err, processed) => {
441
+ const reses = {};
442
+ if (err) {
443
+ done(err);
699
444
  return;
700
445
  }
701
- done(undefined, delete bobj.context[bobj.prop]);
702
- },
703
- 'return': (exec, done, ticks, a, b, obj, context) => done(undefined, b),
704
- 'var': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
705
- exec(ticks, b, scope, context, (err, res) => {
706
- if (err) {
707
- done(err);
708
- return;
709
- }
710
- done(undefined, scope.declare(a, VarType.var, res));
711
- });
712
- },
713
- 'let': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
714
- exec(ticks, b, scope, context, (err, res) => {
715
- if (err) {
716
- done(err);
717
- return;
718
- }
719
- done(undefined, scope.declare(a, VarType.let, res, bobj && bobj.isGlobal));
720
- });
721
- },
722
- 'const': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
723
- exec(ticks, b, scope, context, (err, res) => {
724
- if (err) {
725
- done(err);
726
- return;
727
- }
728
- done(undefined, scope.declare(a, VarType.const, res));
729
- });
730
- },
731
- 'arrowFunc': (exec, done, ticks, a, b, obj, context, scope) => {
732
- a = [...a];
733
- if (typeof obj.b === "string" || obj.b instanceof CodeString) {
734
- obj.b = b = lispifyFunction(new CodeString(obj.b), context.constants);
446
+ for (const i of Object.keys(processed)) {
447
+ const num = resnums[i];
448
+ reses[num] = processed[i];
735
449
  }
736
- if (a.shift()) {
737
- done(undefined, createFunctionAsync(a, b, ticks, context, scope));
450
+ done(undefined, name.replace(/(\\\\)*(\\)?\${(\d+)}/g, (match, $$, $, num) => {
451
+ if ($)
452
+ return match;
453
+ const res = reses[num];
454
+ return ($$ ? $$ : '') + `${valueOrProp(res, context)}`;
455
+ }));
456
+ });
457
+ });
458
+ addOps(18 /* LispType.SpreadArray */, (exec, done, ticks, a, b) => {
459
+ done(undefined, new SpreadArray(b));
460
+ });
461
+ addOps(17 /* LispType.SpreadObject */, (exec, done, ticks, a, b) => {
462
+ done(undefined, new SpreadObject(b));
463
+ });
464
+ addOps(24 /* LispType.Not */, (exec, done, ticks, a, b) => done(undefined, !b));
465
+ addOps(64 /* LispType.Inverse */, (exec, done, ticks, a, b) => done(undefined, ~b));
466
+ addOps(25 /* LispType.IncrementBefore */, (exec, done, ticks, a, b, obj, context) => {
467
+ assignCheck(obj, context);
468
+ done(undefined, ++obj.context[obj.prop]);
469
+ });
470
+ addOps(26 /* LispType.IncrementAfter */, (exec, done, ticks, a, b, obj, context) => {
471
+ assignCheck(obj, context);
472
+ done(undefined, obj.context[obj.prop]++);
473
+ });
474
+ addOps(27 /* LispType.DecrementBefore */, (exec, done, ticks, a, b, obj, context) => {
475
+ assignCheck(obj, context);
476
+ done(undefined, --obj.context[obj.prop]);
477
+ });
478
+ addOps(28 /* LispType.DecrementAfter */, (exec, done, ticks, a, b, obj, context) => {
479
+ assignCheck(obj, context);
480
+ done(undefined, obj.context[obj.prop]--);
481
+ });
482
+ addOps(9 /* LispType.Assign */, (exec, done, ticks, a, b, obj, context) => {
483
+ assignCheck(obj, context);
484
+ done(undefined, (obj.context[obj.prop] = b));
485
+ });
486
+ addOps(66 /* LispType.AddEquals */, (exec, done, ticks, a, b, obj, context) => {
487
+ assignCheck(obj, context);
488
+ done(undefined, (obj.context[obj.prop] += b));
489
+ });
490
+ addOps(65 /* LispType.SubractEquals */, (exec, done, ticks, a, b, obj, context) => {
491
+ assignCheck(obj, context);
492
+ done(undefined, (obj.context[obj.prop] -= b));
493
+ });
494
+ addOps(67 /* LispType.DivideEquals */, (exec, done, ticks, a, b, obj, context) => {
495
+ assignCheck(obj, context);
496
+ done(undefined, (obj.context[obj.prop] /= b));
497
+ });
498
+ addOps(69 /* LispType.MultiplyEquals */, (exec, done, ticks, a, b, obj, context) => {
499
+ assignCheck(obj, context);
500
+ done(undefined, (obj.context[obj.prop] *= b));
501
+ });
502
+ addOps(68 /* LispType.PowerEquals */, (exec, done, ticks, a, b, obj, context) => {
503
+ assignCheck(obj, context);
504
+ done(undefined, (obj.context[obj.prop] **= b));
505
+ });
506
+ addOps(70 /* LispType.ModulusEquals */, (exec, done, ticks, a, b, obj, context) => {
507
+ assignCheck(obj, context);
508
+ done(undefined, (obj.context[obj.prop] %= b));
509
+ });
510
+ addOps(71 /* LispType.BitNegateEquals */, (exec, done, ticks, a, b, obj, context) => {
511
+ assignCheck(obj, context);
512
+ done(undefined, (obj.context[obj.prop] ^= b));
513
+ });
514
+ addOps(72 /* LispType.BitAndEquals */, (exec, done, ticks, a, b, obj, context) => {
515
+ assignCheck(obj, context);
516
+ done(undefined, (obj.context[obj.prop] &= b));
517
+ });
518
+ addOps(73 /* LispType.BitOrEquals */, (exec, done, ticks, a, b, obj, context) => {
519
+ assignCheck(obj, context);
520
+ done(undefined, (obj.context[obj.prop] |= b));
521
+ });
522
+ addOps(76 /* LispType.ShiftLeftEquals */, (exec, done, ticks, a, b, obj, context) => {
523
+ assignCheck(obj, context);
524
+ done(undefined, (obj.context[obj.prop] <<= b));
525
+ });
526
+ addOps(75 /* LispType.ShiftRightEquals */, (exec, done, ticks, a, b, obj, context) => {
527
+ assignCheck(obj, context);
528
+ done(undefined, (obj.context[obj.prop] >>= b));
529
+ });
530
+ addOps(74 /* LispType.UnsignedShiftRightEquals */, (exec, done, ticks, a, b, obj, context) => {
531
+ assignCheck(obj, context);
532
+ done(undefined, (obj.context[obj.prop] >>= b));
533
+ });
534
+ addOps(57 /* LispType.LargerThan */, (exec, done, ticks, a, b) => done(undefined, a > b));
535
+ addOps(56 /* LispType.SmallerThan */, (exec, done, ticks, a, b) => done(undefined, a < b));
536
+ addOps(55 /* LispType.LargerEqualThan */, (exec, done, ticks, a, b) => done(undefined, a >= b));
537
+ addOps(54 /* LispType.SmallerEqualThan */, (exec, done, ticks, a, b) => done(undefined, a <= b));
538
+ addOps(52 /* LispType.Equal */, (exec, done, ticks, a, b) => done(undefined, a == b));
539
+ addOps(32 /* LispType.StrictEqual */, (exec, done, ticks, a, b) => done(undefined, a === b));
540
+ addOps(53 /* LispType.NotEqual */, (exec, done, ticks, a, b) => done(undefined, a != b));
541
+ addOps(31 /* LispType.StrictNotEqual */, (exec, done, ticks, a, b) => done(undefined, a !== b));
542
+ addOps(29 /* LispType.And */, (exec, done, ticks, a, b) => done(undefined, a && b));
543
+ addOps(30 /* LispType.Or */, (exec, done, ticks, a, b) => done(undefined, a || b));
544
+ addOps(77 /* LispType.BitAnd */, (exec, done, ticks, a, b) => done(undefined, a & b));
545
+ addOps(78 /* LispType.BitOr */, (exec, done, ticks, a, b) => done(undefined, a | b));
546
+ addOps(33 /* LispType.Plus */, (exec, done, ticks, a, b) => done(undefined, a + b));
547
+ addOps(47 /* LispType.Minus */, (exec, done, ticks, a, b) => done(undefined, a - b));
548
+ addOps(59 /* LispType.Positive */, (exec, done, ticks, a, b) => done(undefined, +b));
549
+ addOps(58 /* LispType.Negative */, (exec, done, ticks, a, b) => done(undefined, -b));
550
+ addOps(48 /* LispType.Divide */, (exec, done, ticks, a, b) => done(undefined, a / b));
551
+ addOps(79 /* LispType.BitNegate */, (exec, done, ticks, a, b) => done(undefined, a ^ b));
552
+ addOps(50 /* LispType.Multiply */, (exec, done, ticks, a, b) => done(undefined, a * b));
553
+ addOps(51 /* LispType.Modulus */, (exec, done, ticks, a, b) => done(undefined, a % b));
554
+ addOps(80 /* LispType.BitShiftLeft */, (exec, done, ticks, a, b) => done(undefined, a << b));
555
+ addOps(81 /* LispType.BitShiftRight */, (exec, done, ticks, a, b) => done(undefined, a >> b));
556
+ addOps(82 /* LispType.BitUnsignedShiftRight */, (exec, done, ticks, a, b) => done(undefined, a >>> b));
557
+ addOps(60 /* LispType.Typeof */, (exec, done, ticks, a, b, obj, context, scope) => {
558
+ exec(ticks, b, scope, context, (e, prop) => {
559
+ done(undefined, typeof valueOrProp(prop, context));
560
+ });
561
+ });
562
+ addOps(62 /* LispType.Instanceof */, (exec, done, ticks, a, b) => done(undefined, a instanceof b));
563
+ addOps(63 /* LispType.In */, (exec, done, ticks, a, b) => done(undefined, a in b));
564
+ addOps(61 /* LispType.Delete */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
565
+ if (bobj.context === undefined) {
566
+ done(undefined, true);
567
+ return;
568
+ }
569
+ assignCheck(bobj, context, 'delete');
570
+ if (bobj.isVariable) {
571
+ done(undefined, false);
572
+ return;
573
+ }
574
+ done(undefined, delete bobj.context?.[bobj.prop]);
575
+ });
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));
579
+ });
580
+ addOps(3 /* LispType.Let */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
581
+ done(undefined, scope.declare(a, "let" /* VarType.let */, b, bobj && bobj.isGlobal));
582
+ });
583
+ addOps(4 /* LispType.Const */, (exec, done, ticks, a, b, obj, context, scope) => {
584
+ done(undefined, scope.declare(a, "const" /* VarType.const */, b));
585
+ });
586
+ addOps(11 /* LispType.ArrowFunction */, (exec, done, ticks, a, b, obj, context, scope) => {
587
+ a = [...a];
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);
738
591
  }
739
592
  else {
740
- done(undefined, createFunction(a, b, ticks, context, scope));
593
+ throw new SandboxError('Unevaluated code detected, JIT not allowed');
741
594
  }
742
- },
743
- 'function': (exec, done, ticks, a, b, obj, context, scope) => {
744
- if (typeof obj.b === "string" || obj.b instanceof CodeString) {
745
- obj.b = b = lispifyFunction(new CodeString(obj.b), context.constants);
746
- }
747
- let isAsync = a.shift();
748
- let name = a.shift();
749
- let func;
750
- if (isAsync) {
751
- func = createFunctionAsync(a, b, ticks, context, scope, name);
595
+ }
596
+ if (a.shift()) {
597
+ done(undefined, createFunctionAsync(a, b, ticks, context, scope));
598
+ }
599
+ else {
600
+ done(undefined, createFunction(a, b, ticks, context, scope));
601
+ }
602
+ });
603
+ addOps(37 /* LispType.Function */, (exec, done, ticks, a, b, obj, context, scope) => {
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);
752
607
  }
753
608
  else {
754
- func = createFunction(a, b, ticks, context, scope, name);
755
- }
756
- if (name) {
757
- scope.declare(name, VarType.var, func);
758
- }
759
- done(undefined, func);
760
- },
761
- 'inlineFunction': (exec, done, ticks, a, b, obj, context, scope) => {
762
- if (typeof obj.b === "string" || obj.b instanceof CodeString) {
763
- obj.b = b = lispifyFunction(new CodeString(obj.b), context.constants);
764
- }
765
- let isAsync = a.shift();
766
- let name = a.shift();
767
- if (name) {
768
- scope = new Scope(scope, {});
609
+ throw new SandboxError('Unevaluated code detected, JIT not allowed');
769
610
  }
770
- let func;
771
- if (isAsync) {
772
- func = createFunctionAsync(a, b, ticks, context, scope, name);
611
+ }
612
+ const isAsync = a.shift();
613
+ const name = a.shift();
614
+ let func;
615
+ if (isAsync === 88 /* LispType.True */) {
616
+ func = createFunctionAsync(a, b, ticks, context, scope, name);
617
+ }
618
+ else {
619
+ func = createFunction(a, b, ticks, context, scope, name);
620
+ }
621
+ if (name) {
622
+ scope.declare(name, "var" /* VarType.var */, func);
623
+ }
624
+ done(undefined, func);
625
+ });
626
+ addOps(10 /* LispType.InlineFunction */, (exec, done, ticks, a, b, obj, context, scope) => {
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);
773
630
  }
774
631
  else {
775
- func = createFunction(a, b, ticks, context, scope, name);
776
- }
777
- if (name) {
778
- scope.declare(name, VarType.let, func);
779
- }
780
- done(undefined, func);
781
- },
782
- 'loop': (exec, done, ticks, a, b, obj, context, scope) => {
783
- const [checkFirst, startInternal, getIterator, startStep, step, condition, beforeStep] = a;
784
- let loop = true;
785
- const loopScope = new Scope(scope, {});
786
- let internalVars = {
787
- '$$obj': undefined
788
- };
789
- const interalScope = new Scope(loopScope, internalVars);
790
- if (exec === execAsync) {
791
- (async () => {
792
- let ad;
793
- ad = asyncDone((d) => exec(ticks, startStep, loopScope, context, d));
794
- internalVars['$$obj'] = (ad = asyncDone((d) => exec(ticks, getIterator, loopScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
795
- ad = asyncDone((d) => exec(ticks, startInternal, interalScope, context, d));
796
- if (checkFirst)
797
- loop = (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
798
- while (loop) {
799
- let innerLoopVars = {};
800
- ad = asyncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
801
- ad.isInstant === true ? ad.instant : (await ad.p).result;
802
- let res = await executeTreeAsync(ticks, context, b, [new Scope(loopScope, innerLoopVars)], "loop");
803
- if (res instanceof ExecReturn && res.returned) {
804
- done(undefined, res);
805
- return;
806
- }
807
- if (res instanceof ExecReturn && res.breakLoop) {
808
- break;
809
- }
810
- ad = asyncDone((d) => exec(ticks, step, interalScope, context, d));
811
- loop = (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
812
- }
813
- done();
814
- })().catch(done);
632
+ throw new SandboxError('Unevaluated code detected, JIT not allowed');
815
633
  }
816
- else {
817
- syncDone((d) => exec(ticks, startStep, loopScope, context, d));
818
- internalVars['$$obj'] = syncDone((d) => exec(ticks, getIterator, loopScope, context, d)).result;
819
- syncDone((d) => exec(ticks, startInternal, interalScope, context, d));
634
+ }
635
+ const isAsync = a.shift();
636
+ const name = a.shift();
637
+ if (name) {
638
+ scope = new Scope(scope, {});
639
+ }
640
+ let func;
641
+ if (isAsync === 88 /* LispType.True */) {
642
+ func = createFunctionAsync(a, b, ticks, context, scope, name);
643
+ }
644
+ else {
645
+ func = createFunction(a, b, ticks, context, scope, name);
646
+ }
647
+ if (name) {
648
+ scope.declare(name, "let" /* VarType.let */, func);
649
+ }
650
+ done(undefined, func);
651
+ });
652
+ addOps(38 /* LispType.Loop */, (exec, done, ticks, a, b, obj, context, scope) => {
653
+ const [checkFirst, startInternal, getIterator, startStep, step, condition, beforeStep] = a;
654
+ let loop = true;
655
+ const loopScope = new Scope(scope, {});
656
+ const internalVars = {
657
+ $$obj: undefined,
658
+ };
659
+ const interalScope = new Scope(loopScope, internalVars);
660
+ if (exec === execAsync) {
661
+ (async () => {
662
+ let ad;
663
+ ad = asyncDone((d) => exec(ticks, startStep, loopScope, context, d));
664
+ internalVars['$$obj'] =
665
+ (ad = asyncDone((d) => exec(ticks, getIterator, loopScope, context, d))).isInstant === true
666
+ ? ad.instant
667
+ : (await ad.p).result;
668
+ ad = asyncDone((d) => exec(ticks, startInternal, interalScope, context, d));
820
669
  if (checkFirst)
821
- loop = (syncDone((d) => exec(ticks, condition, interalScope, context, d))).result;
670
+ loop =
671
+ (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant ===
672
+ true
673
+ ? ad.instant
674
+ : (await ad.p).result;
822
675
  while (loop) {
823
- let innerLoopVars = {};
824
- syncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
825
- let res = executeTree(ticks, context, b, [new Scope(loopScope, innerLoopVars)], "loop");
676
+ const innerLoopVars = {};
677
+ ad = asyncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
678
+ ad.isInstant === true ? ad.instant : (await ad.p).result;
679
+ const res = await executeTreeAsync(ticks, context, b, [new Scope(loopScope, innerLoopVars)], 'loop');
826
680
  if (res instanceof ExecReturn && res.returned) {
827
681
  done(undefined, res);
828
682
  return;
@@ -830,116 +684,152 @@ let ops2 = {
830
684
  if (res instanceof ExecReturn && res.breakLoop) {
831
685
  break;
832
686
  }
833
- syncDone((d) => exec(ticks, step, interalScope, context, d));
834
- loop = (syncDone((d) => exec(ticks, condition, interalScope, context, d))).result;
687
+ ad = asyncDone((d) => exec(ticks, step, interalScope, context, d));
688
+ loop =
689
+ (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant ===
690
+ true
691
+ ? ad.instant
692
+ : (await ad.p).result;
835
693
  }
836
694
  done();
837
- }
838
- },
839
- 'loopAction': (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
840
- if ((inLoopOrSwitch === "switch" && a === "continue") || !inLoopOrSwitch) {
841
- throw new SandboxError("Illegal " + a + " statement");
842
- }
843
- done(undefined, new ExecReturn(context.ctx.auditReport, undefined, false, a === "break", a === "continue"));
844
- },
845
- 'if': (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
846
- if (!(b instanceof If)) {
847
- throw new SyntaxError('Invalid if');
848
- }
849
- exec(ticks, a, scope, context, (err, res) => {
850
- if (err) {
851
- done(err);
695
+ })().catch(done);
696
+ }
697
+ else {
698
+ syncDone((d) => exec(ticks, startStep, loopScope, context, d));
699
+ internalVars['$$obj'] = syncDone((d) => exec(ticks, getIterator, loopScope, context, d)).result;
700
+ syncDone((d) => exec(ticks, startInternal, interalScope, context, d));
701
+ if (checkFirst)
702
+ loop = syncDone((d) => exec(ticks, condition, interalScope, context, d)).result;
703
+ while (loop) {
704
+ const innerLoopVars = {};
705
+ syncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
706
+ const res = executeTree(ticks, context, b, [new Scope(loopScope, innerLoopVars)], 'loop');
707
+ if (res instanceof ExecReturn && res.returned) {
708
+ done(undefined, res);
852
709
  return;
853
710
  }
854
- executeTreeWithDone(exec, done, ticks, context, valueOrProp(res, context) ? b.t : b.f, [new Scope(scope)], inLoopOrSwitch);
855
- });
856
- },
857
- 'switch': (exec, done, ticks, a, b, obj, context, scope) => {
858
- exec(ticks, a, scope, context, (err, toTest) => {
859
- if (err) {
860
- done(err);
861
- return;
711
+ if (res instanceof ExecReturn && res.breakLoop) {
712
+ break;
862
713
  }
863
- toTest = valueOrProp(toTest, context);
864
- if (exec === execSync) {
714
+ syncDone((d) => exec(ticks, step, interalScope, context, d));
715
+ loop = syncDone((d) => exec(ticks, condition, interalScope, context, d)).result;
716
+ }
717
+ done();
718
+ }
719
+ });
720
+ addOps(86 /* LispType.LoopAction */, (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
721
+ if ((inLoopOrSwitch === 'switch' && a === 'continue') || !inLoopOrSwitch) {
722
+ throw new SandboxError('Illegal ' + a + ' statement');
723
+ }
724
+ done(undefined, new ExecReturn(context.ctx.auditReport, undefined, false, a === 'break', a === 'continue'));
725
+ });
726
+ addOps(13 /* LispType.If */, (exec, done, ticks, a, b, obj, context, scope) => {
727
+ exec(ticks, valueOrProp(a, context) ? b.t : b.f, scope, context, done);
728
+ });
729
+ addOps(15 /* LispType.InlineIf */, (exec, done, ticks, a, b, obj, context, scope) => {
730
+ exec(ticks, valueOrProp(a, context) ? b.t : b.f, scope, context, done);
731
+ });
732
+ addOps(16 /* LispType.InlineIfCase */, (exec, done, ticks, a, b) => done(undefined, new If(a, b)));
733
+ addOps(14 /* LispType.IfCase */, (exec, done, ticks, a, b) => done(undefined, new If(a, b)));
734
+ addOps(40 /* LispType.Switch */, (exec, done, ticks, a, b, obj, context, scope) => {
735
+ exec(ticks, a, scope, context, (err, toTest) => {
736
+ if (err) {
737
+ done(err);
738
+ return;
739
+ }
740
+ toTest = valueOrProp(toTest, context);
741
+ if (exec === execSync) {
742
+ let res;
743
+ let isTrue = false;
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))) {
750
+ if (!caseItem[2])
751
+ continue;
752
+ res = executeTree(ticks, context, caseItem[2], [scope], 'switch');
753
+ if (res.breakLoop)
754
+ break;
755
+ if (res.returned) {
756
+ done(undefined, res);
757
+ return;
758
+ }
759
+ if (!caseItem[1]) {
760
+ // default case
761
+ break;
762
+ }
763
+ }
764
+ }
765
+ done();
766
+ }
767
+ else {
768
+ (async () => {
865
769
  let res;
866
770
  let isTrue = false;
867
- for (let caseItem of b) {
868
- if (isTrue || (isTrue = !caseItem.a || toTest === valueOrProp((syncDone((d) => exec(ticks, caseItem.a, scope, context, d))).result, context))) {
869
- if (!caseItem.b)
771
+ for (const caseItem of b) {
772
+ let ad;
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))) {
781
+ if (!caseItem[2])
870
782
  continue;
871
- res = executeTree(ticks, context, caseItem.b, [scope], "switch");
783
+ res = await executeTreeAsync(ticks, context, caseItem[2], [scope], 'switch');
872
784
  if (res.breakLoop)
873
785
  break;
874
786
  if (res.returned) {
875
787
  done(undefined, res);
876
788
  return;
877
789
  }
878
- if (!caseItem.a) { // default case
790
+ if (!caseItem[1]) {
791
+ // default case
879
792
  break;
880
793
  }
881
794
  }
882
795
  }
883
796
  done();
797
+ })().catch(done);
798
+ }
799
+ });
800
+ });
801
+ addOps(39 /* LispType.Try */, (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
802
+ const [exception, catchBody, finallyBody] = b;
803
+ executeTreeWithDone(exec, (err, res) => {
804
+ executeTreeWithDone(exec, (e) => {
805
+ if (e)
806
+ done(e);
807
+ else if (err) {
808
+ const sc = {};
809
+ if (exception)
810
+ sc[exception] = err;
811
+ executeTreeWithDone(exec, done, ticks, context, catchBody, [new Scope(scope)], inLoopOrSwitch);
884
812
  }
885
813
  else {
886
- (async () => {
887
- let res;
888
- let isTrue = false;
889
- for (let caseItem of b) {
890
- let ad;
891
- if (isTrue || (isTrue = !caseItem.a || toTest === valueOrProp((ad = asyncDone((d) => exec(ticks, caseItem.a, scope, context, d))).isInstant === true ? ad.instant : (await ad.p).result, context))) {
892
- if (!caseItem.b)
893
- continue;
894
- res = await executeTreeAsync(ticks, context, caseItem.b, [scope], "switch");
895
- if (res.breakLoop)
896
- break;
897
- if (res.returned) {
898
- done(undefined, res);
899
- return;
900
- }
901
- if (!caseItem.a) { // default case
902
- break;
903
- }
904
- }
905
- }
906
- done();
907
- })().catch(done);
814
+ done(undefined, res);
908
815
  }
909
- });
910
- },
911
- 'try': (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
912
- const [exception, catchBody, finallyBody] = b;
913
- executeTreeWithDone(exec, (err, res) => {
914
- executeTreeWithDone(exec, (e) => {
915
- if (e)
916
- done(e);
917
- else if (err) {
918
- let sc = {};
919
- if (exception)
920
- sc[exception] = err;
921
- executeTreeWithDone(exec, done, ticks, context, catchBody, [new Scope(scope)], inLoopOrSwitch);
922
- }
923
- else {
924
- done(undefined, res);
925
- }
926
- }, ticks, context, finallyBody, [new Scope(scope, {})]);
927
- }, ticks, context, a, [new Scope(scope)], inLoopOrSwitch);
928
- },
929
- 'void': (exec, done, ticks, a) => { done(); },
930
- 'new': (exec, done, ticks, a, b, obj, context) => {
931
- if (!context.ctx.globalsWhitelist.has(a) && !sandboxedFunctions.has(a)) {
932
- throw new SandboxError(`Object construction not allowed: ${a.constructor.name}`);
933
- }
934
- done(undefined, new a(...b));
935
- },
936
- 'throw': (exec, done, ticks, a, b) => { done(b); },
937
- 'multi': (exec, done, ticks, a) => done(undefined, a.pop())
938
- };
939
- export let ops = new Map();
940
- for (let op in ops2) {
941
- ops.set(op, ops2[op]);
942
- }
816
+ }, ticks, context, finallyBody, [new Scope(scope, {})]);
817
+ }, ticks, context, a, [new Scope(scope)], inLoopOrSwitch);
818
+ });
819
+ addOps(87 /* LispType.Void */, (exec, done) => {
820
+ done();
821
+ });
822
+ addOps(45 /* LispType.New */, (exec, done, ticks, a, b, obj, context) => {
823
+ if (!context.ctx.globalsWhitelist.has(a) && !sandboxedFunctions.has(a)) {
824
+ throw new SandboxError(`Object construction not allowed: ${a.constructor.name}`);
825
+ }
826
+ done(undefined, new a(...b));
827
+ });
828
+ addOps(46 /* LispType.Throw */, (exec, done, ticks, a, b) => {
829
+ done(b);
830
+ });
831
+ addOps(43 /* LispType.Expression */, (exec, done, ticks, a) => done(undefined, a.pop()));
832
+ addOps(0 /* LispType.None */, (exec, done) => done());
943
833
  function valueOrProp(a, context) {
944
834
  if (a instanceof Prop)
945
835
  return a.get(context);
@@ -956,7 +846,7 @@ export function execMany(ticks, exec, tree, done, scope, context, inLoopOrSwitch
956
846
  }
957
847
  }
958
848
  function _execManySync(ticks, tree, done, scope, context, inLoopOrSwitch) {
959
- let ret = [];
849
+ const ret = [];
960
850
  for (let i = 0; i < tree.length; i++) {
961
851
  let res;
962
852
  try {
@@ -970,17 +860,25 @@ function _execManySync(ticks, tree, done, scope, context, inLoopOrSwitch) {
970
860
  done(undefined, res);
971
861
  return;
972
862
  }
863
+ if (isLisp(tree[i]) && tree[i][0] === 8 /* LispType.Return */) {
864
+ done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
865
+ return;
866
+ }
973
867
  ret.push(res);
974
868
  }
975
869
  done(undefined, ret);
976
870
  }
977
871
  async function _execManyAsync(ticks, tree, done, scope, context, inLoopOrSwitch) {
978
- let ret = [];
872
+ const ret = [];
979
873
  for (let i = 0; i < tree.length; i++) {
980
874
  let res;
981
875
  try {
982
876
  let ad;
983
- 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;
984
882
  }
985
883
  catch (e) {
986
884
  done(e);
@@ -990,6 +888,10 @@ async function _execManyAsync(ticks, tree, done, scope, context, inLoopOrSwitch)
990
888
  done(undefined, res);
991
889
  return;
992
890
  }
891
+ if (isLisp(tree[i]) && tree[i][0] === 8 /* LispType.Return */) {
892
+ done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
893
+ return;
894
+ }
993
895
  ret.push(res);
994
896
  }
995
897
  done(undefined, ret);
@@ -1006,13 +908,12 @@ export function asyncDone(callback) {
1006
908
  instant = result;
1007
909
  resolve({ result });
1008
910
  }
1009
- ;
1010
911
  });
1011
912
  });
1012
913
  return {
1013
914
  isInstant,
1014
915
  instant,
1015
- p
916
+ p,
1016
917
  };
1017
918
  }
1018
919
  export function syncDone(callback) {
@@ -1034,13 +935,16 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
1034
935
  resolve();
1035
936
  };
1036
937
  });
1037
- if (_execNoneRecurse(ticks, tree, scope, context, done, true, inLoopOrSwitch)) {
1038
- }
1039
- else if (tree instanceof Lisp) {
938
+ if (!_execNoneRecurse(ticks, tree, scope, context, done, true, inLoopOrSwitch) && isLisp(tree)) {
939
+ let op = tree[0];
1040
940
  let obj;
1041
941
  try {
1042
942
  let ad;
1043
- obj = (ad = asyncDone((d) => execAsync(ticks, tree.a, 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;
1044
948
  }
1045
949
  catch (e) {
1046
950
  done(e);
@@ -1054,16 +958,15 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
1054
958
  done(e);
1055
959
  return;
1056
960
  }
1057
- let op = tree.op;
1058
- if (op === '?prop' || op === '?call') {
961
+ if (op === 20 /* LispType.PropOptional */ || op === 21 /* LispType.CallOptional */) {
1059
962
  if (a === undefined || a === null) {
1060
963
  done(undefined, optional);
1061
964
  return;
1062
965
  }
1063
- op = op.slice(1);
966
+ op = op === 20 /* LispType.PropOptional */ ? 1 /* LispType.Prop */ : 5 /* LispType.Call */;
1064
967
  }
1065
968
  if (a === optional) {
1066
- if (op === 'prop' || op === 'call') {
969
+ if (op === 1 /* LispType.Prop */ || op === 5 /* LispType.Call */) {
1067
970
  done(undefined, a);
1068
971
  return;
1069
972
  }
@@ -1074,7 +977,11 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
1074
977
  let bobj;
1075
978
  try {
1076
979
  let ad;
1077
- bobj = (ad = asyncDone((d) => execAsync(ticks, tree.b, 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;
1078
985
  }
1079
986
  catch (e) {
1080
987
  done(e);
@@ -1093,7 +1000,7 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
1093
1000
  }
1094
1001
  if (ops.has(op)) {
1095
1002
  try {
1096
- 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);
1097
1004
  }
1098
1005
  catch (err) {
1099
1006
  done(err);
@@ -1106,12 +1013,11 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
1106
1013
  await p;
1107
1014
  }
1108
1015
  export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
1109
- if (_execNoneRecurse(ticks, tree, scope, context, done, false, inLoopOrSwitch)) {
1110
- }
1111
- else if (tree instanceof Lisp) {
1016
+ if (!_execNoneRecurse(ticks, tree, scope, context, done, false, inLoopOrSwitch) && isLisp(tree)) {
1017
+ let op = tree[0];
1112
1018
  let obj;
1113
1019
  try {
1114
- obj = syncDone((d) => execSync(ticks, tree.a, scope, context, d, inLoopOrSwitch)).result;
1020
+ obj = syncDone((d) => execSync(ticks, tree[1], scope, context, d, inLoopOrSwitch)).result;
1115
1021
  }
1116
1022
  catch (e) {
1117
1023
  done(e);
@@ -1125,16 +1031,15 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
1125
1031
  done(e);
1126
1032
  return;
1127
1033
  }
1128
- let op = tree.op;
1129
- if (op === '?prop' || op === '?call') {
1034
+ if (op === 20 /* LispType.PropOptional */ || op === 21 /* LispType.CallOptional */) {
1130
1035
  if (a === undefined || a === null) {
1131
1036
  done(undefined, optional);
1132
1037
  return;
1133
1038
  }
1134
- op = op.slice(1);
1039
+ op = op === 20 /* LispType.PropOptional */ ? 1 /* LispType.Prop */ : 5 /* LispType.Call */;
1135
1040
  }
1136
1041
  if (a === optional) {
1137
- if (op === 'prop' || op === 'call') {
1042
+ if (op === 1 /* LispType.Prop */ || op === 5 /* LispType.Call */) {
1138
1043
  done(undefined, a);
1139
1044
  return;
1140
1045
  }
@@ -1144,7 +1049,7 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
1144
1049
  }
1145
1050
  let bobj;
1146
1051
  try {
1147
- bobj = syncDone((d) => execSync(ticks, tree.b, scope, context, d, inLoopOrSwitch)).result;
1052
+ bobj = syncDone((d) => execSync(ticks, tree[2], scope, context, d, inLoopOrSwitch)).result;
1148
1053
  }
1149
1054
  catch (e) {
1150
1055
  done(e);
@@ -1163,7 +1068,7 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
1163
1068
  }
1164
1069
  if (ops.has(op)) {
1165
1070
  try {
1166
- 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);
1167
1072
  }
1168
1073
  catch (err) {
1169
1074
  done(err);
@@ -1174,20 +1079,29 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
1174
1079
  }
1175
1080
  }
1176
1081
  }
1177
- const unexecTypes = new Set(['arrowFunc', 'function', 'inlineFunction', 'loop', 'try', 'switch', 'if', '?', 'typeof']);
1082
+ const unexecTypes = new Set([
1083
+ 11 /* LispType.ArrowFunction */,
1084
+ 37 /* LispType.Function */,
1085
+ 10 /* LispType.InlineFunction */,
1086
+ 38 /* LispType.Loop */,
1087
+ 39 /* LispType.Try */,
1088
+ 40 /* LispType.Switch */,
1089
+ 14 /* LispType.IfCase */,
1090
+ 16 /* LispType.InlineIfCase */,
1091
+ 60 /* LispType.Typeof */,
1092
+ ]);
1093
+ export const currentTicks = { current: { ticks: BigInt(0) } };
1178
1094
  function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSwitch) {
1179
- var _a;
1180
1095
  const exec = isAsync ? execAsync : execSync;
1181
- if (context.ctx.options.executionQuota <= ticks.ticks) {
1182
- if (typeof context.ctx.options.onExecutionQuotaReached === 'function' && context.ctx.options.onExecutionQuotaReached(ticks, scope, context, tree)) {
1183
- }
1184
- else {
1185
- done(new SandboxError("Execution quota exceeded"));
1186
- 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;
1187
1101
  }
1188
1102
  }
1189
1103
  ticks.ticks++;
1190
- currentTicks = ticks;
1104
+ currentTicks.current = ticks;
1191
1105
  if (tree instanceof Prop) {
1192
1106
  try {
1193
1107
  done(undefined, tree.get(context));
@@ -1199,18 +1113,26 @@ function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSw
1199
1113
  else if (tree === optional) {
1200
1114
  done();
1201
1115
  }
1202
- else if (Array.isArray(tree) && tree.lisp === lispArrayKey) {
1203
- execMany(ticks, exec, tree, done, scope, context, inLoopOrSwitch);
1116
+ else if (Array.isArray(tree) && !isLisp(tree)) {
1117
+ if (tree[0] === 0 /* LispType.None */) {
1118
+ done();
1119
+ }
1120
+ else {
1121
+ execMany(ticks, exec, tree, done, scope, context, inLoopOrSwitch);
1122
+ }
1204
1123
  }
1205
- else if (!(tree instanceof Lisp)) {
1124
+ else if (!isLisp(tree)) {
1206
1125
  done(undefined, tree);
1207
1126
  }
1208
- else if (tree.op === 'await') {
1127
+ else if (tree[0] === 42 /* LispType.Block */) {
1128
+ execMany(ticks, exec, tree[1], done, scope, context, inLoopOrSwitch);
1129
+ }
1130
+ else if (tree[0] === 44 /* LispType.Await */) {
1209
1131
  if (!isAsync) {
1210
1132
  done(new SandboxError("Illegal use of 'await', must be inside async function"));
1211
1133
  }
1212
- else if ((_a = context.ctx.prototypeWhitelist) === null || _a === void 0 ? void 0 : _a.has(Promise.prototype)) {
1213
- execAsync(ticks, tree.a, scope, context, async (e, r) => {
1134
+ else if (context.ctx.prototypeWhitelist?.has(Promise.prototype)) {
1135
+ execAsync(ticks, tree[1], scope, context, async (e, r) => {
1214
1136
  if (e)
1215
1137
  done(e);
1216
1138
  else
@@ -1226,9 +1148,9 @@ function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSw
1226
1148
  done(new SandboxError('Async/await is not permitted'));
1227
1149
  }
1228
1150
  }
1229
- else if (unexecTypes.has(tree.op)) {
1151
+ else if (unexecTypes.has(tree[0])) {
1230
1152
  try {
1231
- ops.get(tree.op)(exec, done, ticks, tree.a, tree.b, tree, context, scope, undefined, inLoopOrSwitch);
1153
+ ops.get(tree[0])?.(exec, done, ticks, tree[1], tree[2], tree, context, scope, undefined, inLoopOrSwitch);
1232
1154
  }
1233
1155
  catch (err) {
1234
1156
  done(err);
@@ -1244,7 +1166,9 @@ export function executeTree(ticks, context, executionTree, scopes = [], inLoopOr
1244
1166
  }
1245
1167
  export async function executeTreeAsync(ticks, context, executionTree, scopes = [], inLoopOrSwitch) {
1246
1168
  let ad;
1247
- 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;
1248
1172
  }
1249
1173
  function executeTreeWithDone(exec, done, ticks, context, executionTree, scopes = [], inLoopOrSwitch) {
1250
1174
  if (!executionTree) {
@@ -1256,8 +1180,8 @@ function executeTreeWithDone(exec, done, ticks, context, executionTree, scopes =
1256
1180
  }
1257
1181
  let scope = context.ctx.globalScope;
1258
1182
  let s;
1259
- while (s = scopes.shift()) {
1260
- if (typeof s !== "object")
1183
+ while ((s = scopes.shift())) {
1184
+ if (typeof s !== 'object')
1261
1185
  continue;
1262
1186
  if (s instanceof Scope) {
1263
1187
  scope = s;
@@ -1304,7 +1228,7 @@ function _executeWithDoneSync(done, ticks, context, executionTree, scope, inLoop
1304
1228
  done(undefined, res);
1305
1229
  return;
1306
1230
  }
1307
- if (current instanceof Lisp && current.op === 'return') {
1231
+ if (isLisp(current) && current[0] === 8 /* LispType.Return */) {
1308
1232
  done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
1309
1233
  return;
1310
1234
  }
@@ -1336,7 +1260,7 @@ async function _executeWithDoneAsync(done, ticks, context, executionTree, scope,
1336
1260
  done(undefined, res);
1337
1261
  return;
1338
1262
  }
1339
- if (current instanceof Lisp && current.op === 'return') {
1263
+ if (isLisp(current) && current[0] === 8 /* LispType.Return */) {
1340
1264
  done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
1341
1265
  return;
1342
1266
  }