@rezless/vm 0.4.0 → 0.6.0

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 (148) hide show
  1. package/dist/builtins/base64.d.ts.map +1 -1
  2. package/dist/builtins/base64.js +29 -2
  3. package/dist/builtins/base64.js.map +1 -1
  4. package/dist/builtins/chat.d.ts +7 -1
  5. package/dist/builtins/chat.d.ts.map +1 -1
  6. package/dist/builtins/chat.js +26 -29
  7. package/dist/builtins/chat.js.map +1 -1
  8. package/dist/builtins/dataserver.d.ts +2 -1
  9. package/dist/builtins/dataserver.d.ts.map +1 -1
  10. package/dist/builtins/dataserver.js +5 -4
  11. package/dist/builtins/dataserver.js.map +1 -1
  12. package/dist/builtins/debug.d.ts +4 -0
  13. package/dist/builtins/debug.d.ts.map +1 -0
  14. package/dist/builtins/debug.js +7 -0
  15. package/dist/builtins/debug.js.map +1 -0
  16. package/dist/builtins/http.d.ts +8 -1
  17. package/dist/builtins/http.d.ts.map +1 -1
  18. package/dist/builtins/http.js +87 -9
  19. package/dist/builtins/http.js.map +1 -1
  20. package/dist/builtins/identity.d.ts +2 -0
  21. package/dist/builtins/identity.d.ts.map +1 -1
  22. package/dist/builtins/identity.js +9 -1
  23. package/dist/builtins/identity.js.map +1 -1
  24. package/dist/builtins/index.d.ts.map +1 -1
  25. package/dist/builtins/index.js +37 -7
  26. package/dist/builtins/index.js.map +1 -1
  27. package/dist/builtins/inventory.d.ts +13 -2
  28. package/dist/builtins/inventory.d.ts.map +1 -1
  29. package/dist/builtins/inventory.js +82 -43
  30. package/dist/builtins/inventory.js.map +1 -1
  31. package/dist/builtins/json.d.ts.map +1 -1
  32. package/dist/builtins/json.js +11 -36
  33. package/dist/builtins/json.js.map +1 -1
  34. package/dist/builtins/link-info.d.ts +1 -1
  35. package/dist/builtins/link-info.d.ts.map +1 -1
  36. package/dist/builtins/link-info.js +2 -2
  37. package/dist/builtins/link-info.js.map +1 -1
  38. package/dist/builtins/linksetdata.d.ts.map +1 -1
  39. package/dist/builtins/linksetdata.js +298 -31
  40. package/dist/builtins/linksetdata.js.map +1 -1
  41. package/dist/builtins/listen.d.ts +3 -1
  42. package/dist/builtins/listen.d.ts.map +1 -1
  43. package/dist/builtins/listen.js +9 -1
  44. package/dist/builtins/listen.js.map +1 -1
  45. package/dist/builtins/lists.d.ts +21 -0
  46. package/dist/builtins/lists.d.ts.map +1 -1
  47. package/dist/builtins/lists.js +82 -38
  48. package/dist/builtins/lists.js.map +1 -1
  49. package/dist/builtins/math.d.ts +27 -4
  50. package/dist/builtins/math.d.ts.map +1 -1
  51. package/dist/builtins/math.js +118 -41
  52. package/dist/builtins/math.js.map +1 -1
  53. package/dist/builtins/memory.d.ts +11 -0
  54. package/dist/builtins/memory.d.ts.map +1 -0
  55. package/dist/builtins/memory.js +17 -0
  56. package/dist/builtins/memory.js.map +1 -0
  57. package/dist/builtins/permissions.d.ts +18 -0
  58. package/dist/builtins/permissions.d.ts.map +1 -0
  59. package/dist/builtins/permissions.js +17 -0
  60. package/dist/builtins/permissions.js.map +1 -0
  61. package/dist/builtins/prim-accessors.d.ts +1 -0
  62. package/dist/builtins/prim-accessors.d.ts.map +1 -1
  63. package/dist/builtins/prim-accessors.js +44 -42
  64. package/dist/builtins/prim-accessors.js.map +1 -1
  65. package/dist/builtins/prim-params.d.ts +1 -1
  66. package/dist/builtins/prim-params.d.ts.map +1 -1
  67. package/dist/builtins/prim-params.js +19 -11
  68. package/dist/builtins/prim-params.js.map +1 -1
  69. package/dist/builtins/strings.d.ts.map +1 -1
  70. package/dist/builtins/strings.js +37 -33
  71. package/dist/builtins/strings.js.map +1 -1
  72. package/dist/builtins/time.d.ts +2 -0
  73. package/dist/builtins/time.d.ts.map +1 -1
  74. package/dist/builtins/time.js +2 -0
  75. package/dist/builtins/time.js.map +1 -1
  76. package/dist/clock.d.ts +23 -9
  77. package/dist/clock.d.ts.map +1 -1
  78. package/dist/clock.js +40 -13
  79. package/dist/clock.js.map +1 -1
  80. package/dist/dispatch.d.ts.map +1 -1
  81. package/dist/dispatch.js +10 -3
  82. package/dist/dispatch.js.map +1 -1
  83. package/dist/env.d.ts +14 -3
  84. package/dist/env.d.ts.map +1 -1
  85. package/dist/env.js +50 -10
  86. package/dist/env.js.map +1 -1
  87. package/dist/index.d.ts +2 -0
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +1 -0
  90. package/dist/index.js.map +1 -1
  91. package/dist/interpreter.d.ts.map +1 -1
  92. package/dist/interpreter.js +44 -23
  93. package/dist/interpreter.js.map +1 -1
  94. package/dist/inventory.d.ts +2 -0
  95. package/dist/inventory.d.ts.map +1 -1
  96. package/dist/inventory.js +4 -0
  97. package/dist/inventory.js.map +1 -1
  98. package/dist/keys.d.ts +6 -0
  99. package/dist/keys.d.ts.map +1 -0
  100. package/dist/keys.js +20 -0
  101. package/dist/keys.js.map +1 -0
  102. package/dist/linkset.d.ts +28 -3
  103. package/dist/linkset.d.ts.map +1 -1
  104. package/dist/linkset.js +66 -7
  105. package/dist/linkset.js.map +1 -1
  106. package/dist/memory.d.ts +55 -0
  107. package/dist/memory.d.ts.map +1 -0
  108. package/dist/memory.js +235 -0
  109. package/dist/memory.js.map +1 -0
  110. package/dist/prim-params.d.ts +5 -0
  111. package/dist/prim-params.d.ts.map +1 -1
  112. package/dist/prim-params.js +187 -107
  113. package/dist/prim-params.js.map +1 -1
  114. package/dist/prim.d.ts +6 -1
  115. package/dist/prim.d.ts.map +1 -1
  116. package/dist/prim.js +23 -3
  117. package/dist/prim.js.map +1 -1
  118. package/dist/runtime.d.ts +14 -1
  119. package/dist/runtime.d.ts.map +1 -1
  120. package/dist/script.d.ts +35 -2
  121. package/dist/script.d.ts.map +1 -1
  122. package/dist/script.js +127 -34
  123. package/dist/script.js.map +1 -1
  124. package/dist/values/coerce.d.ts +11 -0
  125. package/dist/values/coerce.d.ts.map +1 -1
  126. package/dist/values/coerce.js +65 -38
  127. package/dist/values/coerce.js.map +1 -1
  128. package/dist/values/format.d.ts +24 -16
  129. package/dist/values/format.d.ts.map +1 -1
  130. package/dist/values/format.js +42 -25
  131. package/dist/values/format.js.map +1 -1
  132. package/dist/values/list-types.d.ts +2 -0
  133. package/dist/values/list-types.d.ts.map +1 -1
  134. package/dist/values/list-types.js +4 -0
  135. package/dist/values/list-types.js.map +1 -1
  136. package/dist/values/ops.d.ts +2 -1
  137. package/dist/values/ops.d.ts.map +1 -1
  138. package/dist/values/ops.js +13 -5
  139. package/dist/values/ops.js.map +1 -1
  140. package/dist/values/utf8.d.ts +3 -0
  141. package/dist/values/utf8.d.ts.map +1 -0
  142. package/dist/values/utf8.js +14 -0
  143. package/dist/values/utf8.js.map +1 -0
  144. package/dist/world.d.ts +29 -0
  145. package/dist/world.d.ts.map +1 -0
  146. package/dist/world.js +29 -0
  147. package/dist/world.js.map +1 -0
  148. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/builtins/time.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/builtins/time.ts"],"names":[],"mappings":"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"}
package/dist/clock.d.ts CHANGED
@@ -6,8 +6,8 @@
6
6
  * it by calling `llSleep` or `llSetTimerEvent`. Real wall-clock time is
7
7
  * never read.
8
8
  *
9
- * The queue is **linkset-wide**: every script in the linkset shares one
10
- * `now` and one event queue. Each queued event carries a `target: Script`
9
+ * The queue is **linkset-wide**, or world-wide for linksets in a `World`:
10
+ * every script shares one `now` and one event queue. Each queued event carries a `target: Script`
11
11
  * — the script whose handler will run when the event fires. Per-script
12
12
  * state (timer interval, llGetTime reference) lives on `ScriptClockView`,
13
13
  * a thin facade exposed to builtins as `ctx.state.clock`.
@@ -21,6 +21,8 @@ export interface QueuedEvent {
21
21
  readonly event: string;
22
22
  readonly payload: Record<string, unknown>;
23
23
  }
24
+ /** Events a script can hold in its queue; more are dropped, as in Second Life. */
25
+ export declare const MAX_PENDING_EVENTS = 64;
24
26
  /** Linkset-wide clock. One instance per Linkset. */
25
27
  export declare class LinksetClock {
26
28
  readonly startUnixTime: number;
@@ -31,24 +33,34 @@ export declare class LinksetClock {
31
33
  /** Wall-clock time in microseconds since the Unix epoch, floored. */
32
34
  unixMicros(): number;
33
35
  private readonly queue;
34
- /** Schedule a one-shot event on `target`'s handler at virtual time `at`. */
36
+ /**
37
+ * Schedule a one-shot event on `target`'s handler at virtual time `at`.
38
+ * A script holds at most MAX_PENDING_EVENTS queued events, counting those
39
+ * parked while it is stopped; further events are dropped.
40
+ */
35
41
  schedule(target: Script, at: number, event: string, payload?: Record<string, unknown>): void;
36
42
  /** Move the clock forward unconditionally; does not drain queues. */
37
43
  advance(ms: number): void;
38
44
  /**
39
- * Pop and return the next due event (`at <= now`) considering all queued
45
+ * Pop and return the next due event (`at <= horizon`, default `now`) considering all queued
40
46
  * one-shots and every script's recurring timer. Returns `null` when no
41
47
  * event is ready.
42
48
  *
43
49
  * Recurring timers fire once per script per interval; their next fire
44
50
  * timestamp is advanced by `at + interval` (not `now + interval`) so that
45
- * long advances catch up on every missed fire.
51
+ * long advances catch up on every missed fire. Ticks that fall due while
52
+ * the script is busy (e.g. in llSleep) collapse into one event delivered
53
+ * when it finishes, and the interval restarts from there.
46
54
  */
47
- takeNextDue(scripts: ReadonlyArray<Script>): QueuedEvent | null;
55
+ takeNextDue(scripts: ReadonlyArray<Script>, horizon?: number): QueuedEvent | null;
48
56
  /** Snapshot of the pending one-shot queue. Read-only; for inspection/tests. */
49
57
  pendingEvents(): readonly QueuedEvent[];
50
- /** Remove every queued event whose target is `script`. Used on reset. */
51
- purgeTarget(script: Script): void;
58
+ /**
59
+ * Remove every queued event whose target is `script` and that is due by
60
+ * `upTo` (default: all of them), except events named `keep`. Used on reset
61
+ * and state change.
62
+ */
63
+ purgeTarget(script: Script, upTo?: number, keep?: string): void;
52
64
  }
53
65
  /**
54
66
  * Per-script clock facade. Builtins read `ctx.state.clock` and call
@@ -58,12 +70,14 @@ export declare class LinksetClock {
58
70
  export declare class ScriptClockView {
59
71
  private readonly linksetClock;
60
72
  private readonly self;
61
- /** Reference time for `llGetTime`/`llResetTime` (virtual ms). */
73
+ /** Reference time for `llGetTime`/`llResetTime` (virtual ms); the script's creation, reset or last llResetTime. */
62
74
  timeReferenceMs: number;
63
75
  /** Recurring timer interval in ms; 0 = no timer. */
64
76
  timerIntervalMs: number;
65
77
  /** Virtual time at which the next timer event fires. */
66
78
  timerNextFireMs: number;
79
+ /** Virtual time at which the script's last handler finished, when it took time (llSleep, delays). */
80
+ busyUntilMs: number;
67
81
  constructor(linksetClock: LinksetClock, self: () => Script);
68
82
  get now(): number;
69
83
  /** Schedule a one-shot event on this script. */
@@ -1 +1 @@
1
- {"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC1C;AAED,oDAAoD;AACpD,qBAAa,YAAY;IAKX,QAAQ,CAAC,aAAa;IAJlC,2EAA2E;IAC3E,GAAG,SAAI;IAEP,iEAAiE;IACjE,YAAqB,aAAa,SAAI,EAAI;IAE1C,qEAAqE;IACrE,UAAU,IAAI,MAAM,CAEnB;IAED,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAE1C,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI,CAE/F;IAED,qEAAqE;IACrE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAGxB;IAED;;;;;;;;OAQG;IACH,WAAW,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,WAAW,GAAG,IAAI,CAmC9D;IAED,+EAA+E;IAC/E,aAAa,IAAI,SAAS,WAAW,EAAE,CAEtC;IAED,yEAAyE;IACzE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAIhC;CACF;AAED;;;;GAIG;AACH,qBAAa,eAAe;IASxB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI;IATvB,iEAAiE;IACjE,eAAe,SAAI;IACnB,oDAAoD;IACpD,eAAe,SAAI;IACnB,wDAAwD;IACxD,eAAe,SAAI;IAEnB,YACmB,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,MAAM,MAAM,EACjC;IAEJ,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,gDAAgD;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI,CAE/E;IAED,sDAAsD;IACtD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI,CAEjG;IAED,WAAW,IAAI,IAAI,CAGlB;IAED,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAOjC;IAED,sDAAsD;IACtD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAExB;IAED,qEAAqE;IACrE,UAAU,IAAI,MAAM,CAEnB;IAED,cAAc,IAAI,MAAM,CAEvB;IAED,cAAc,IAAI,IAAI,CAErB;CACF"}
1
+ {"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC1C;AAED,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,KAAK,CAAA;AAEpC,oDAAoD;AACpD,qBAAa,YAAY;IAKX,QAAQ,CAAC,aAAa;IAJlC,2EAA2E;IAC3E,GAAG,SAAI;IAEP,iEAAiE;IACjE,YAAqB,aAAa,SAAI,EAAI;IAE1C,qEAAqE;IACrE,UAAU,IAAI,MAAM,CAEnB;IAED,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAE1C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI,CAO/F;IAED,qEAAqE;IACrE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAGxB;IAED;;;;;;;;;;OAUG;IACH,WAAW,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,SAAW,GAAG,WAAW,GAAG,IAAI,CAsClF;IAED,+EAA+E;IAC/E,aAAa,IAAI,SAAS,WAAW,EAAE,CAEtC;IAED;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,SAAW,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAKhE;CACF;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAWxB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI;IAXvB,mHAAmH;IACnH,eAAe,EAAE,MAAM,CAAA;IACvB,oDAAoD;IACpD,eAAe,SAAI;IACnB,wDAAwD;IACxD,eAAe,SAAI;IACnB,qGAAqG;IACrG,WAAW,SAAI;IAEf,YACmB,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,MAAM,MAAM,EAGpC;IAED,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,gDAAgD;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI,CAE/E;IAED,sDAAsD;IACtD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI,CAEjG;IAED,WAAW,IAAI,IAAI,CAGlB;IAED,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAOjC;IAED,sDAAsD;IACtD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAExB;IAED,qEAAqE;IACrE,UAAU,IAAI,MAAM,CAEnB;IAED,cAAc,IAAI,MAAM,CAEvB;IAED,cAAc,IAAI,IAAI,CAErB;CACF"}
package/dist/clock.js CHANGED
@@ -1,3 +1,5 @@
1
+ /** Events a script can hold in its queue; more are dropped, as in Second Life. */
2
+ export const MAX_PENDING_EVENTS = 64;
1
3
  /** Linkset-wide clock. One instance per Linkset. */
2
4
  export class LinksetClock {
3
5
  startUnixTime;
@@ -12,8 +14,20 @@ export class LinksetClock {
12
14
  return Math.floor(this.startUnixTime * 1e6 + this.now * 1000);
13
15
  }
14
16
  queue = [];
15
- /** Schedule a one-shot event on `target`'s handler at virtual time `at`. */
17
+ /**
18
+ * Schedule a one-shot event on `target`'s handler at virtual time `at`.
19
+ * A script holds at most MAX_PENDING_EVENTS queued events, counting those
20
+ * parked while it is stopped; further events are dropped.
21
+ */
16
22
  schedule(target, at, event, payload = {}) {
23
+ if (event !== '__reset') {
24
+ let pending = target.parkedEvents.length;
25
+ for (const e of this.queue)
26
+ if (e.target === target)
27
+ pending++;
28
+ if (pending >= MAX_PENDING_EVENTS)
29
+ return;
30
+ }
17
31
  this.queue.push({ at, target, event, payload });
18
32
  }
19
33
  /** Move the clock forward unconditionally; does not drain queues. */
@@ -23,20 +37,22 @@ export class LinksetClock {
23
37
  this.now += ms;
24
38
  }
25
39
  /**
26
- * Pop and return the next due event (`at <= now`) considering all queued
40
+ * Pop and return the next due event (`at <= horizon`, default `now`) considering all queued
27
41
  * one-shots and every script's recurring timer. Returns `null` when no
28
42
  * event is ready.
29
43
  *
30
44
  * Recurring timers fire once per script per interval; their next fire
31
45
  * timestamp is advanced by `at + interval` (not `now + interval`) so that
32
- * long advances catch up on every missed fire.
46
+ * long advances catch up on every missed fire. Ticks that fall due while
47
+ * the script is busy (e.g. in llSleep) collapse into one event delivered
48
+ * when it finishes, and the interval restarts from there.
33
49
  */
34
- takeNextDue(scripts) {
50
+ takeNextDue(scripts, horizon = this.now) {
35
51
  let bestIdx = -1;
36
52
  let bestAt = Infinity;
37
53
  for (let i = 0; i < this.queue.length; i++) {
38
54
  const e = this.queue[i];
39
- if (e.at <= this.now && e.at < bestAt) {
55
+ if (e.at <= horizon && e.at < bestAt) {
40
56
  bestAt = e.at;
41
57
  bestIdx = i;
42
58
  }
@@ -50,9 +66,12 @@ export class LinksetClock {
50
66
  if (s.dead || !s.running)
51
67
  continue;
52
68
  const v = s.clockView;
53
- if (v.timerIntervalMs > 0 && v.timerNextFireMs <= this.now && v.timerNextFireMs < bestTimerAt) {
54
- bestTimerAt = v.timerNextFireMs;
55
- bestTimerScript = s;
69
+ if (v.timerIntervalMs > 0 && v.timerNextFireMs <= horizon) {
70
+ const due = Math.max(v.timerNextFireMs, v.busyUntilMs);
71
+ if (due < bestTimerAt) {
72
+ bestTimerAt = due;
73
+ bestTimerScript = s;
74
+ }
56
75
  }
57
76
  }
58
77
  if (bestIdx === -1 && bestTimerScript === null)
@@ -71,10 +90,15 @@ export class LinksetClock {
71
90
  pendingEvents() {
72
91
  return this.queue.slice();
73
92
  }
74
- /** Remove every queued event whose target is `script`. Used on reset. */
75
- purgeTarget(script) {
93
+ /**
94
+ * Remove every queued event whose target is `script` and that is due by
95
+ * `upTo` (default: all of them), except events named `keep`. Used on reset
96
+ * and state change.
97
+ */
98
+ purgeTarget(script, upTo = Infinity, keep) {
76
99
  for (let i = this.queue.length - 1; i >= 0; i--) {
77
- if (this.queue[i].target === script)
100
+ const e = this.queue[i];
101
+ if (e.target === script && e.at <= upTo && e.event !== keep)
78
102
  this.queue.splice(i, 1);
79
103
  }
80
104
  }
@@ -87,15 +111,18 @@ export class LinksetClock {
87
111
  export class ScriptClockView {
88
112
  linksetClock;
89
113
  self;
90
- /** Reference time for `llGetTime`/`llResetTime` (virtual ms). */
91
- timeReferenceMs = 0;
114
+ /** Reference time for `llGetTime`/`llResetTime` (virtual ms); the script's creation, reset or last llResetTime. */
115
+ timeReferenceMs;
92
116
  /** Recurring timer interval in ms; 0 = no timer. */
93
117
  timerIntervalMs = 0;
94
118
  /** Virtual time at which the next timer event fires. */
95
119
  timerNextFireMs = 0;
120
+ /** Virtual time at which the script's last handler finished, when it took time (llSleep, delays). */
121
+ busyUntilMs = 0;
96
122
  constructor(linksetClock, self) {
97
123
  this.linksetClock = linksetClock;
98
124
  this.self = self;
125
+ this.timeReferenceMs = linksetClock.now;
99
126
  }
100
127
  get now() {
101
128
  return this.linksetClock.now;
package/dist/clock.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"clock.js","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"clock.js","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAe,WAAW,EAAE,MAAM,cAAc,CAAA;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAGjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,8DAA8D;AAC9D,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE7D;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,GAC5B,QAAQ,GAAG,SAAS,CAkBtB"}
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAe,WAAW,EAAE,MAAM,cAAc,CAAA;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAGjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAIzC,8DAA8D;AAC9D,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE7D;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,GAC5B,QAAQ,GAAG,SAAS,CAoBtB"}
package/dist/dispatch.js CHANGED
@@ -2,6 +2,7 @@ import { defaultValueFor } from './values/types.js';
2
2
  import { BUILTIN_SPECS } from './generated/functions.js';
3
3
  import { REAL_BUILTINS } from './builtins/index.js';
4
4
  import { own } from './own.js';
5
+ import { ScriptRemovedSignal } from './builtins/inventory.js';
5
6
  /** Look up the generated spec for a function name, if any. */
6
7
  export function specFor(name) {
7
8
  return own(BUILTIN_SPECS, name);
@@ -14,7 +15,7 @@ export function specFor(name) {
14
15
  */
15
16
  export function callBuiltin(dctx, name, args) {
16
17
  const spec = specFor(name);
17
- const impl = dctx.mocks[name] ?? own(REAL_BUILTINS, name) ?? makeStub(name);
18
+ const impl = dctx.mocks[name] ?? own(REAL_BUILTINS, name) ?? makeStub(dctx.script, name);
18
19
  const ctx = {
19
20
  state: dctx.state,
20
21
  spec,
@@ -22,6 +23,7 @@ export function callBuiltin(dctx, name, args) {
22
23
  prim: dctx.script.host,
23
24
  linkset: dctx.script.linkset,
24
25
  };
26
+ const startedAt = dctx.state.clock.now;
25
27
  const result = impl(ctx, args);
26
28
  dctx.state.calls.push({ name, args, returned: result });
27
29
  // Call log timestamps when the script invoked the function (pre-delay);
@@ -29,15 +31,20 @@ export function callBuiltin(dctx, name, args) {
29
31
  if (spec && spec.delay > 0) {
30
32
  dctx.state.clock.advance(spec.delay * 1000);
31
33
  }
34
+ if (dctx.state.lifecycle.removed && dctx.state.clock.now > startedAt)
35
+ throw new ScriptRemovedSignal();
32
36
  return result;
33
37
  }
34
- function makeStub(name) {
38
+ function makeStub(script, name) {
35
39
  const spec = specFor(name);
36
40
  if (!spec) {
37
41
  return () => {
38
42
  throw new Error(`LSL function '${name}' has no implementation (not in the LSL definitions; use script.mock to provide it)`);
39
43
  };
40
44
  }
41
- return () => defaultValueFor(spec.returnType);
45
+ return () => {
46
+ script.reportStub(name);
47
+ return defaultValueFor(spec.returnType);
48
+ };
42
49
  }
43
50
  //# sourceMappingURL=dispatch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAE9B,8DAA8D;AAC9D,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,GAAG,CAAC,aAA4C,EAAE,IAAI,CAAC,CAAA;AAChE,CAAC;AAQD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,IAAqB,EACrB,IAAY,EACZ,IAA6B;IAE7B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC3E,MAAM,GAAG,GAAgB;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI;QACJ,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;QACtB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;KAC7B,CAAA;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;IACvD,wEAAwE;IACxE,yEAAyE;IACzE,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAA;IAC7C,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,GAAG,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,qFAAqF,CAAC,CAAA;QAC7H,CAAC,CAAA;IACH,CAAC;IACD,OAAO,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;AAC/C,CAAC"}
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAE7D,8DAA8D;AAC9D,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,GAAG,CAAC,aAA4C,EAAE,IAAI,CAAC,CAAA;AAChE,CAAC;AAQD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,IAAqB,EACrB,IAAY,EACZ,IAA6B;IAE7B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACxF,MAAM,GAAG,GAAgB;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI;QACJ,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;QACtB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;KAC7B,CAAA;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAA;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;IACvD,wEAAwE;IACxE,yEAAyE;IACzE,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAA;IAC7C,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,SAAS;QAAE,MAAM,IAAI,mBAAmB,EAAE,CAAA;IACrG,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,MAAc,EAAE,IAAY;IAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,GAAG,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,qFAAqF,CAAC,CAAA;QAC7H,CAAC,CAAA;IACH,CAAC;IACD,OAAO,GAAG,EAAE;QACV,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QACvB,OAAO,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACzC,CAAC,CAAA;AACH,CAAC"}
package/dist/env.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { EvalResult, LslType } from './values/types.js';
2
+ import type { Memory } from './memory.js';
2
3
  /**
3
4
  * Lexical environment with a single parent pointer. The interpreter pushes
4
5
  * a new env when entering a block / handler and discards on exit. Globals
@@ -6,8 +7,15 @@ import type { EvalResult, LslType } from './values/types.js';
6
7
  */
7
8
  export declare class Env {
8
9
  private readonly parent;
10
+ private readonly memory;
11
+ private readonly global;
9
12
  private readonly slots;
10
- constructor(parent?: Env | null);
13
+ /**
14
+ * `memory` (inherited by child scopes) is charged for the variables this
15
+ * scope holds: every global, and the strings and lists among locals. Call
16
+ * frames pay for the rest of a local's stack space.
17
+ */
18
+ constructor(parent?: Env | null, memory?: Memory | null, global?: boolean);
11
19
  /** Declare a new variable in the current scope. Coerces init to declared type. */
12
20
  declare(name: string, type: LslType, init?: EvalResult): void;
13
21
  /**
@@ -24,10 +32,13 @@ export declare class Env {
24
32
  /** Assign to an existing variable. Coerces to declared type. */
25
33
  set(name: string, value: EvalResult): EvalResult;
26
34
  hasOwn(name: string): boolean;
27
- /** Drop every slot in *this* scope; doesn't touch the parent chain. */
35
+ /** Drop every slot in *this* scope and give back its memory; doesn't touch the parent chain. */
28
36
  clear(): void;
29
- /** Open a child scope. */
37
+ /** Open a child scope for locals. */
30
38
  push(): Env;
39
+ private store;
40
+ private charge;
41
+ private bytesFor;
31
42
  private findSlot;
32
43
  }
33
44
  //# sourceMappingURL=env.d.ts.map
package/dist/env.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAS5D;;;;GAIG;AACH,qBAAa,GAAG;IAGF,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAEhD,YAA6B,MAAM,GAAE,GAAG,GAAG,IAAW,EAAI;IAE1D,kFAAkF;IAClF,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,CAM5D;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,CAQnE;IAED,iEAAiE;IACjE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAI5B;IAED,gEAAgE;IAChE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAK/C;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5B;IAED,uEAAuE;IACvE,KAAK,IAAI,IAAI,CAEZ;IAED,0BAA0B;IAC1B,IAAI,IAAI,GAAG,CAEV;IAED,OAAO,CAAC,QAAQ;CASjB"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAA;AAGtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AASzC;;;;GAIG;AACH,qBAAa,GAAG;IASZ,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAEhD;;;;OAIG;IACH,YACmB,MAAM,GAAE,GAAG,GAAG,IAAW,EACzB,MAAM,GAAE,MAAM,GAAG,IAAW,EAC5B,MAAM,UAAkB,EACvC;IAEJ,kFAAkF;IAClF,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,CAQ5D;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,CAQnE;IAED,iEAAiE;IACjE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAI5B;IAED,gEAAgE;IAChE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAQ/C;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5B;IAED,gGAAgG;IAChG,KAAK,IAAI,IAAI,CAKZ;IAED,qCAAqC;IACrC,IAAI,IAAI,GAAG,CAEV;IAED,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,QAAQ;CASjB"}
package/dist/env.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { defaultEvalFor } from './values/types.js';
2
2
  import { coerce } from './values/coerce.js';
3
+ import { globalBytes, listBytes, stringBytes } from './memory.js';
3
4
  /**
4
5
  * Lexical environment with a single parent pointer. The interpreter pushes
5
6
  * a new env when entering a block / handler and discards on exit. Globals
@@ -7,9 +8,18 @@ import { coerce } from './values/coerce.js';
7
8
  */
8
9
  export class Env {
9
10
  parent;
11
+ memory;
12
+ global;
10
13
  slots = new Map();
11
- constructor(parent = null) {
14
+ /**
15
+ * `memory` (inherited by child scopes) is charged for the variables this
16
+ * scope holds: every global, and the strings and lists among locals. Call
17
+ * frames pay for the rest of a local's stack space.
18
+ */
19
+ constructor(parent = null, memory = null, global = memory !== null) {
12
20
  this.parent = parent;
21
+ this.memory = memory;
22
+ this.global = global;
13
23
  }
14
24
  /** Declare a new variable in the current scope. Coerces init to declared type. */
15
25
  declare(name, type, init) {
@@ -17,7 +27,9 @@ export class Env {
17
27
  throw new Error(`variable '${name}' already declared in this scope`);
18
28
  }
19
29
  const value = init ? coerce(init, type) : defaultEvalFor(type);
20
- this.slots.set(name, { type, value });
30
+ const bytes = this.bytesFor(value);
31
+ this.charge(bytes);
32
+ this.slots.set(name, { type, value, bytes });
21
33
  }
22
34
  /**
23
35
  * Declare-or-reset: like `declare`, but if `name` already exists in this
@@ -31,7 +43,7 @@ export class Env {
31
43
  const slot = this.slots.get(name);
32
44
  if (slot) {
33
45
  slot.type = type;
34
- slot.value = init ? coerce(init, type) : defaultEvalFor(type);
46
+ this.store(slot, init ? coerce(init, type) : defaultEvalFor(type));
35
47
  return;
36
48
  }
37
49
  this.declare(name, type, init);
@@ -45,22 +57,50 @@ export class Env {
45
57
  }
46
58
  /** Assign to an existing variable. Coerces to declared type. */
47
59
  set(name, value) {
48
- const slot = this.findSlot(name);
49
- if (!slot)
50
- throw new Error(`undefined variable '${name}'`);
51
- slot.value = coerce(value, slot.type);
60
+ const slot = this.slots.get(name);
61
+ if (!slot) {
62
+ if (!this.parent)
63
+ throw new Error(`undefined variable '${name}'`);
64
+ return this.parent.set(name, value);
65
+ }
66
+ this.store(slot, coerce(value, slot.type));
52
67
  return slot.value;
53
68
  }
54
69
  hasOwn(name) {
55
70
  return this.slots.has(name);
56
71
  }
57
- /** Drop every slot in *this* scope; doesn't touch the parent chain. */
72
+ /** Drop every slot in *this* scope and give back its memory; doesn't touch the parent chain. */
58
73
  clear() {
74
+ let bytes = 0;
75
+ for (const s of this.slots.values())
76
+ bytes += s.bytes;
77
+ this.charge(-bytes);
59
78
  this.slots.clear();
60
79
  }
61
- /** Open a child scope. */
80
+ /** Open a child scope for locals. */
62
81
  push() {
63
- return new Env(this);
82
+ return new Env(this, this.memory, false);
83
+ }
84
+ store(slot, value) {
85
+ const bytes = this.bytesFor(value);
86
+ this.charge(bytes - slot.bytes);
87
+ slot.value = value;
88
+ slot.bytes = bytes;
89
+ }
90
+ charge(bytes) {
91
+ if (this.global)
92
+ this.memory.alloc(bytes);
93
+ else
94
+ this.memory?.allocLocal(bytes);
95
+ }
96
+ bytesFor(value) {
97
+ if (!this.memory)
98
+ return 0;
99
+ if (this.global)
100
+ return globalBytes(value.type, value.value);
101
+ if (value.type === 'string')
102
+ return stringBytes(value.value);
103
+ return value.type === 'list' ? listBytes(value.value) : 0;
64
104
  }
65
105
  findSlot(name) {
66
106
  let env = this;
package/dist/env.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAO3C;;;;GAIG;AACH,MAAM,OAAO,GAAG;IAGe,MAAM;IAFlB,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAA;IAEhD,YAA6B,MAAM,GAAe,IAAI;sBAAzB,MAAM;IAAsB,CAAC;IAE1D,kFAAkF;IAClF,OAAO,CAAC,IAAY,EAAE,IAAa,EAAE,IAAiB;QACpD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,kCAAkC,CAAC,CAAA;QACtE,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QAC9D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACvC,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,IAAY,EAAE,IAAa,EAAE,IAAiB;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;YAChB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;YAC7D,OAAM;QACR,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IAChC,CAAC;IAED,iEAAiE;IACjE,GAAG,CAAC,IAAY;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAChC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,GAAG,CAAC,CAAA;QAC1D,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,gEAAgE;IAChE,GAAG,CAAC,IAAY,EAAE,KAAiB;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAChC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,GAAG,CAAC,CAAA;QAC1D,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QACrC,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC7B,CAAC;IAED,uEAAuE;IACvE,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;IACpB,CAAC;IAED,0BAA0B;IAC1B,IAAI;QACF,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,CAAA;IACtB,CAAC;IAEO,QAAQ,CAAC,IAAY;QAC3B,IAAI,GAAG,GAAe,IAAI,CAAA;QAC1B,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAC7B,IAAI,CAAC;gBAAE,OAAO,CAAC,CAAA;YACf,GAAG,GAAG,GAAG,CAAC,MAAM,CAAA;QAClB,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,6 +5,8 @@ export { CoverageCollector, buildCoveragePlan, mergeReports } from './coverage.j
5
5
  export type { CoveragePlan, CoverageReport, StatementInfo, StatementHit, StatementKind, BranchInfo, BranchHit, BranchKind, FunctionInfo, FunctionHit, FunctionKind, StateInfo, StateHit, } from './coverage.js';
6
6
  export { Linkset, LINK_THIS, LINK_SET, LINK_ALL_OTHERS, LINK_ALL_CHILDREN, LINK_ROOT } from './linkset.js';
7
7
  export type { LinksetOptions } from './linkset.js';
8
+ export { World } from './world.js';
9
+ export type { WorldOptions, RegionCorner } from './world.js';
8
10
  export { Prim } from './prim.js';
9
11
  export type { PrimOptions } from './prim.js';
10
12
  export { InventoryType, makeInventoryItem } from './inventory.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACnE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAClF,YAAY,EACV,YAAY,EACZ,cAAc,EACd,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,SAAS,EACT,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,SAAS,EACT,QAAQ,GACT,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC1G,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACjE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACjF,YAAY,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,EACT,QAAQ,EACR,WAAW,GACZ,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5E,OAAO,EACL,WAAW,EACX,aAAa,EACb,QAAQ,EACR,eAAe,GAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAChF,cAAc,0BAA0B,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACnE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAClF,YAAY,EACV,YAAY,EACZ,cAAc,EACd,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,SAAS,EACT,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,SAAS,EACT,QAAQ,GACT,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC1G,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACjE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACjF,YAAY,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,EACT,QAAQ,EACR,WAAW,GACZ,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5E,OAAO,EACL,WAAW,EACX,aAAa,EACb,QAAQ,EACR,eAAe,GAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAChF,cAAc,0BAA0B,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ export { Script } from './script.js';
2
2
  export { typecheck } from './typecheck.js';
3
3
  export { CoverageCollector, buildCoveragePlan, mergeReports } from './coverage.js';
4
4
  export { Linkset, LINK_THIS, LINK_SET, LINK_ALL_OTHERS, LINK_ALL_CHILDREN, LINK_ROOT } from './linkset.js';
5
+ export { World } from './world.js';
5
6
  export { Prim } from './prim.js';
6
7
  export { InventoryType, makeInventoryItem } from './inventory.js';
7
8
  export { ZERO_VECTOR, ZERO_ROTATION, NULL_KEY, defaultValueFor, } from './values/types.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAgBlF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE1G,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAWjE,OAAO,EACL,WAAW,EACX,aAAa,EACb,QAAQ,EACR,eAAe,GAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEnD,cAAc,0BAA0B,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAgBlF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE1G,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAWjE,OAAO,EACL,WAAW,EACX,aAAa,EACb,QAAQ,EACR,eAAe,GAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEnD,cAAc,0BAA0B,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../src/interpreter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,YAAY,EAiBZ,mBAAmB,EAEpB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAuC,MAAM,mBAAmB,CAAA;AAKxF,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAG9B;;;;;;;;;GASG;AAEH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;IACrD,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAA;IACrB,mFAAmF;IACnF,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IAChE,wFAAwF;IACxF,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAA;IAC/D,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,WAAW,EAAE,IAAI,CAAA;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,EAAE,OAAO,CAAA;CACjD;AAUD,qBAAa,iBAAiB;aACA,MAAM,EAAE,MAAM;IAA1C,YAA4B,MAAM,EAAE,MAAM,EAAI;CAC/C;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,kBAAkB,EACvB,OAAO,EAAE,YAAY,EACrB,IAAI,GAAE,aAAa,CAAC,UAAU,CAAM,GACnC,IAAI,CAmBN;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,kBAAkB,EACvB,EAAE,EAAE,mBAAmB,EACvB,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,GAC9B,UAAU,CA6BZ"}
1
+ {"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../src/interpreter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,YAAY,EAiBZ,mBAAmB,EAEpB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAuC,MAAM,mBAAmB,CAAA;AAKxF,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAI9B;;;;;;;;;GASG;AAEH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;IACrD,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAA;IACrB,mFAAmF;IACnF,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IAChE,wFAAwF;IACxF,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAA;IAC/D,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,WAAW,EAAE,IAAI,CAAA;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,EAAE,OAAO,CAAA;CACjD;AAUD,qBAAa,iBAAiB;aACA,MAAM,EAAE,MAAM;IAA1C,YAA4B,MAAM,EAAE,MAAM,EAAI;CAC/C;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,kBAAkB,EACvB,OAAO,EAAE,YAAY,EACrB,IAAI,GAAE,aAAa,CAAC,UAAU,CAAM,GACnC,IAAI,CAsBN;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,kBAAkB,EACvB,EAAE,EAAE,mBAAmB,EACvB,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,GAC9B,UAAU,CAsCZ"}
@@ -5,6 +5,7 @@ import { typedList } from './values/list-types.js';
5
5
  import { applyBinary, applyUnary, reduceCompound, truthy } from './values/ops.js';
6
6
  import { Env } from './env.js';
7
7
  import { own } from './own.js';
8
+ import { StackHeapCollision, frameBytes } from './memory.js';
8
9
  class ReturnSignal {
9
10
  value;
10
11
  constructor(value) {
@@ -30,13 +31,14 @@ export function execHandler(ctx, handler, args = []) {
30
31
  // the body BlockStatement here.
31
32
  ctx.state.coverage.hitStatement(handler.body.loc);
32
33
  }
34
+ const locals = ctx.state.memory.locals;
33
35
  const env = ctx.globals.push();
34
- // Bind handler params (each carries declared LSL type).
35
- handler.params.forEach((p, i) => {
36
- const a = args[i] ?? defaultEvalFor(p.typeName);
37
- env.declare(p.name, p.typeName, a);
38
- });
39
36
  try {
37
+ // Bind handler params (each carries declared LSL type).
38
+ handler.params.forEach((p, i) => {
39
+ const a = args[i] ?? defaultEvalFor(p.typeName);
40
+ env.declare(p.name, p.typeName, a);
41
+ });
40
42
  execBlock(ctx, env, handler.body);
41
43
  }
42
44
  catch (e) {
@@ -44,6 +46,9 @@ export function execHandler(ctx, handler, args = []) {
44
46
  return;
45
47
  throw e;
46
48
  }
49
+ finally {
50
+ ctx.state.memory.releaseLocals(locals);
51
+ }
47
52
  }
48
53
  /**
49
54
  * Invoke a user-defined function. Pushes a fresh env (no closures —
@@ -55,12 +60,16 @@ export function callUserFunction(ctx, fn, args) {
55
60
  ctx.state.coverage.hitFunction(fn.loc);
56
61
  ctx.state.coverage.hitStatement(fn.body.loc);
57
62
  }
63
+ const memory = ctx.state.memory;
64
+ const frame = frameBytes(fn);
65
+ const locals = memory.locals;
66
+ memory.pushFrame(frame);
58
67
  const env = ctx.globals.push();
59
- fn.params.forEach((p, i) => {
60
- const a = args[i] ?? defaultEvalFor(p.typeName);
61
- env.declare(p.name, p.typeName, a);
62
- });
63
68
  try {
69
+ fn.params.forEach((p, i) => {
70
+ const a = args[i] ?? defaultEvalFor(p.typeName);
71
+ env.declare(p.name, p.typeName, a);
72
+ });
64
73
  execBlock(ctx, env, fn.body);
65
74
  }
66
75
  catch (e) {
@@ -75,8 +84,15 @@ export function callUserFunction(ctx, fn, args) {
75
84
  // the calling handler and could land on an unrelated same-named label.
76
85
  throw new Error(`jump to undefined label '${e.label}' in function '${fn.name}'`);
77
86
  }
87
+ // The host ran out of stack before the memory model did.
88
+ if (e instanceof RangeError)
89
+ throw new StackHeapCollision();
78
90
  throw e;
79
91
  }
92
+ finally {
93
+ memory.releaseLocals(locals);
94
+ memory.popFrame(frame);
95
+ }
80
96
  // Fell off end without explicit return.
81
97
  return fn.returnType ? defaultEvalFor(fn.returnType) : { type: 'void', value: 0 };
82
98
  }
@@ -104,21 +120,26 @@ function execBlock(ctx, env, block) {
104
120
  }
105
121
  }
106
122
  let i = 0;
107
- while (i < block.body.length) {
108
- const stmt = block.body[i];
109
- try {
110
- execStatement(ctx, child, stmt);
111
- i++;
112
- }
113
- catch (e) {
114
- if (e instanceof JumpSignal && labels && labels.has(e.label)) {
115
- // Resume execution at the label.
116
- i = labels.get(e.label) + 1;
117
- continue;
123
+ try {
124
+ while (i < block.body.length) {
125
+ const stmt = block.body[i];
126
+ try {
127
+ execStatement(ctx, child, stmt);
128
+ i++;
129
+ }
130
+ catch (e) {
131
+ if (e instanceof JumpSignal && labels && labels.has(e.label)) {
132
+ // Resume execution at the label.
133
+ i = labels.get(e.label) + 1;
134
+ continue;
135
+ }
136
+ throw e;
118
137
  }
119
- throw e;
120
138
  }
121
139
  }
140
+ finally {
141
+ child.clear();
142
+ }
122
143
  }
123
144
  function execStatement(ctx, env, stmt) {
124
145
  if (ctx.state.coverage)
@@ -281,9 +302,9 @@ function evalListLiteral(ctx, env, e) {
281
302
  };
282
303
  }
283
304
  function evalBinary(ctx, env, e) {
284
- // LSL: && and || are NOT short-circuit. Eager evaluation matches the language.
285
- const left = evalExpression(ctx, env, e.left);
305
+ // LSL: && and || are NOT short-circuit, and the right operand runs first.
286
306
  const right = evalExpression(ctx, env, e.right);
307
+ const left = evalExpression(ctx, env, e.left);
287
308
  return applyBinary(e.operator, left, right);
288
309
  }
289
310
  function evalAssignment(ctx, env, e) {