@hew-lang/sandbox-vm 0.9.3 → 0.10.0-rc1

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.
@@ -1,4 +1,5 @@
1
1
  import { stringValue } from "./strings.js";
2
+ import { cloneEncoding } from "./v1/encoding-storage.js";
2
3
  export { stringValue } from "./strings.js";
3
4
  export const UNIT = { kind: "unit" };
4
5
  const UTF8_ENCODER = new TextEncoder();
@@ -18,7 +19,7 @@ const I64_LITERAL_DECIMAL = /^(?:0|-?[1-9]\d*)$/;
18
19
  export function cloneValue(value) {
19
20
  switch (value.kind) {
20
21
  case "encoding":
21
- return { ...value, value: structuredClone(value.value) };
22
+ return cloneEncoding(value);
22
23
  case "rc":
23
24
  if (value.closed)
24
25
  throw new Error("cannot copy a released Rc");
@@ -69,6 +70,7 @@ export function cloneValue(value) {
69
70
  kind: "record",
70
71
  typeId: value.typeId,
71
72
  shape: value.shape,
73
+ managedCaptures: value.managedCaptures,
72
74
  fields: value.fields.map(cloneValue),
73
75
  };
74
76
  case "enum":
@@ -80,16 +82,13 @@ export function cloneValue(value) {
80
82
  payload: value.payload.map(cloneValue),
81
83
  };
82
84
  case "vector":
83
- return {
84
- kind: "vector",
85
- elementType: value.elementType,
86
- items: value.items.map(cloneValue),
87
- };
85
+ return cloneVector(value);
88
86
  case "dyn":
89
87
  return {
90
88
  kind: "dyn",
91
89
  vtable: value.vtable,
92
90
  value: cloneValue(value.value),
91
+ managedPayload: value.managedPayload,
93
92
  };
94
93
  case "closure":
95
94
  return {
@@ -97,6 +96,7 @@ export function cloneValue(value) {
97
96
  entries: value.entries,
98
97
  specialization: value.specialization,
99
98
  environment: cloneValue(value.environment),
99
+ managedCaptures: value.managedCaptures,
100
100
  };
101
101
  case "map":
102
102
  return {
@@ -110,6 +110,118 @@ export function cloneValue(value) {
110
110
  };
111
111
  }
112
112
  }
113
+ export function vectorStorage(value) {
114
+ if (value.closed)
115
+ throw new Error("cannot read a released vector");
116
+ return (value.storage ??= {
117
+ items: value.items,
118
+ capacity: value.items.length,
119
+ owners: 1,
120
+ bytes: false,
121
+ shareOnCopy: false,
122
+ });
123
+ }
124
+ export function byteVectorValue(items) {
125
+ return {
126
+ kind: "vector",
127
+ elementType: "u8",
128
+ items,
129
+ storage: {
130
+ items,
131
+ capacity: items.length ? Math.max(items.length, 16) : 0,
132
+ owners: 1,
133
+ bytes: true,
134
+ shareOnCopy: true,
135
+ },
136
+ offset: 0,
137
+ };
138
+ }
139
+ function cloneVector(value) {
140
+ const storage = vectorStorage(value);
141
+ // Native Vec clones discard an empty receiver's spare capacity. Bytes
142
+ // clones retain their allocation even when the visible length is zero.
143
+ if (storage.bytes || (storage.shareOnCopy && value.items.length !== 0)) {
144
+ storage.owners++;
145
+ return { ...value, storage, closed: false };
146
+ }
147
+ const items = value.items.map(cloneValue);
148
+ return {
149
+ kind: "vector",
150
+ elementType: value.elementType,
151
+ items,
152
+ storage: { ...storage, items, capacity: items.length, owners: 1 },
153
+ };
154
+ }
155
+ export function sliceByteVector(value, start, end) {
156
+ const storage = vectorStorage(value);
157
+ if (!storage.bytes)
158
+ throw new Error("bytes slice has no bytes storage");
159
+ if (start === end)
160
+ return byteVectorValue([]);
161
+ storage.owners++;
162
+ return {
163
+ kind: "vector",
164
+ elementType: value.elementType,
165
+ items: value.items.slice(start, end),
166
+ storage,
167
+ offset: (value.offset ?? 0) + start,
168
+ };
169
+ }
170
+ /** Establish uniqueness before any mutation, preserving native capacity rules. */
171
+ export function mutableVector(value, needed = value.items.length, appended) {
172
+ let storage = vectorStorage(value);
173
+ let capacity = storage.capacity;
174
+ const detached = storage.owners !== 1;
175
+ if (detached && storage.bytes)
176
+ capacity = Math.max(value.items.length, 16);
177
+ if (needed > capacity) {
178
+ if (storage.bytes)
179
+ capacity = Math.max(Math.min(capacity * 2, 0xffffffff), needed, 16);
180
+ else {
181
+ capacity = capacity || 4;
182
+ while (capacity < needed)
183
+ capacity *= 2;
184
+ }
185
+ }
186
+ if (!Number.isSafeInteger(capacity) ||
187
+ (storage.bytes && capacity > 0xffffffff))
188
+ throw new Error("vector capacity overflow");
189
+ if (detached || capacity !== storage.capacity || appended?.length)
190
+ value.prepareMutation?.(capacity, detached, appended);
191
+ if (detached) {
192
+ const items = value.items.map(cloneValue);
193
+ storage.owners--;
194
+ storage = { ...storage, items, capacity, owners: 1 };
195
+ value.storage = storage;
196
+ value.items = items;
197
+ value.offset = 0;
198
+ }
199
+ if (capacity !== storage.capacity) {
200
+ storage.capacity = capacity;
201
+ value.offset = 0;
202
+ }
203
+ else if (storage.bytes && (value.offset ?? 0) + needed > capacity) {
204
+ value.offset = 0;
205
+ }
206
+ return value;
207
+ }
208
+ /** Consume one handle; only the last backing owner releases its elements. */
209
+ export function releaseVector(value) {
210
+ if (value.closed)
211
+ return [];
212
+ const storage = vectorStorage(value);
213
+ value.closed = true;
214
+ return --storage.owners === 0 ? storage.items : [];
215
+ }
216
+ export function clearByteVector(value) {
217
+ const storage = vectorStorage(value);
218
+ storage.owners--;
219
+ const empty = byteVectorValue([]);
220
+ value.items = empty.items;
221
+ value.storage = empty.storage;
222
+ value.offset = 0;
223
+ return value;
224
+ }
113
225
  export function valueFromLiteral(value) {
114
226
  const taggedI64 = taggedI64Literal(value);
115
227
  if (taggedI64 !== null) {
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@hew-lang/sandbox-vm",
3
- "version": "0.9.3",
3
+ "version": "0.10.0-rc1",
4
4
  "hewSource": {
5
- "commit": "6e4bcf6b089c260bedae59320c68dab2137f5754",
6
- "tag": "v0.9.3",
5
+ "commit": "5672a4d39318d99785a863cd5002d33952eb269e",
6
+ "tag": "v0.10.0-rc1",
7
7
  "dirty": false
8
8
  },
9
9
  "description": "Deterministic TypeScript interpreter for the Hew educational sandbox",
@@ -21,7 +21,7 @@
21
21
  "cli/"
22
22
  ],
23
23
  "dependencies": {
24
- "@hew-lang/wasm": "0.9.3"
24
+ "@hew-lang/wasm": "0.10.0-rc1"
25
25
  },
26
26
  "keywords": [
27
27
  "hew",