warpo 3.3.0 → 3.4.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.
- package/asconfig.schema.json +18 -2
- package/assemblyscript/std/assembly/map.ts +89 -2
- package/create/resolveModule.ts +2 -0
- package/dist/test_runner/core/compiler.js +1 -0
- package/dist/test_runner/core/compiler.js.map +1 -1
- package/package.json +1 -1
- package/types/warpo/index.d.ts +4 -0
- package/warpo_extension/std/warpo/memory.ts +6 -0
package/asconfig.schema.json
CHANGED
|
@@ -89,7 +89,15 @@
|
|
|
89
89
|
"items": {
|
|
90
90
|
"type": "string",
|
|
91
91
|
"description": "Name of a feature to disable.",
|
|
92
|
-
"enum": [
|
|
92
|
+
"enum": [
|
|
93
|
+
"mutable-globals",
|
|
94
|
+
"sign-extension",
|
|
95
|
+
"nontrapping-f2i",
|
|
96
|
+
"bulk-memory",
|
|
97
|
+
"multi-value",
|
|
98
|
+
"tail-call",
|
|
99
|
+
"return-to-br"
|
|
100
|
+
]
|
|
93
101
|
}
|
|
94
102
|
},
|
|
95
103
|
"enable": {
|
|
@@ -98,7 +106,15 @@
|
|
|
98
106
|
"items": {
|
|
99
107
|
"type": "string",
|
|
100
108
|
"description": "Name of a feature to enable.",
|
|
101
|
-
"enum": [
|
|
109
|
+
"enum": [
|
|
110
|
+
"mutable-globals",
|
|
111
|
+
"sign-extension",
|
|
112
|
+
"nontrapping-f2i",
|
|
113
|
+
"bulk-memory",
|
|
114
|
+
"multi-value",
|
|
115
|
+
"tail-call",
|
|
116
|
+
"return-to-br"
|
|
117
|
+
]
|
|
102
118
|
}
|
|
103
119
|
},
|
|
104
120
|
"debug": {
|
|
@@ -57,6 +57,41 @@ function ENTRY_SIZE<K, V>(): usize {
|
|
|
57
57
|
return size;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Forward-only history of entries layouts: the map keeps the latest version,
|
|
62
|
+
* while each iterator keeps the version matching its cursor. Old versions retain
|
|
63
|
+
* removed slot indices, not obsolete entries buffers or references to their contents.
|
|
64
|
+
*/
|
|
65
|
+
class MapIteratorVersion {
|
|
66
|
+
private nextVersion: MapIteratorVersion | null = null;
|
|
67
|
+
// For versions with a successor, null marks clear(); otherwise indices are sorted in the old layout.
|
|
68
|
+
private removedIndices: StaticArray<i32> | null = null;
|
|
69
|
+
|
|
70
|
+
transition(removedIndices: StaticArray<i32> | null): MapIteratorVersion {
|
|
71
|
+
this.removedIndices = removedIndices;
|
|
72
|
+
return (this.nextVersion = new MapIteratorVersion());
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
translateIndex(index: i32): i32 {
|
|
76
|
+
const removedIndices = this.removedIndices;
|
|
77
|
+
if (!removedIndices) return 0;
|
|
78
|
+
// New cursor = old cursor - number of removed slots strictly before it.
|
|
79
|
+
// A removed slot at index is unvisited and must not move the boundary backward.
|
|
80
|
+
let lower = 0;
|
|
81
|
+
let upper = removedIndices.length;
|
|
82
|
+
while (lower < upper) {
|
|
83
|
+
const middle = lower + ((upper - lower) >> 1);
|
|
84
|
+
if (unchecked(removedIndices[middle]) < index) lower = middle + 1;
|
|
85
|
+
else upper = middle;
|
|
86
|
+
}
|
|
87
|
+
return index - lower;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getNext(): MapIteratorVersion {
|
|
91
|
+
return assert(this.nextVersion);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
60
95
|
// @ts-ignore: decorator
|
|
61
96
|
@lazy
|
|
62
97
|
const GET_START = Symbol();
|
|
@@ -65,11 +100,33 @@ const GET_START = Symbol();
|
|
|
65
100
|
@lazy
|
|
66
101
|
const GET_ENTRIES_OFFSET = Symbol();
|
|
67
102
|
|
|
103
|
+
// @ts-ignore: decorator
|
|
104
|
+
@lazy
|
|
105
|
+
const GET_ITERATOR_VERSION = Symbol();
|
|
106
|
+
|
|
68
107
|
class MapIterator<K, V> implements Iterator<[K, V]> {
|
|
108
|
+
// Next physical slot in this.version's layout, not the number of values returned.
|
|
69
109
|
private i: i32 = 0;
|
|
70
|
-
|
|
110
|
+
private map: Map<K, V> | null;
|
|
111
|
+
private version: MapIteratorVersion | null;
|
|
112
|
+
|
|
113
|
+
constructor(map: Map<K, V>) {
|
|
114
|
+
this.map = map;
|
|
115
|
+
this.version = map[GET_ITERATOR_VERSION]();
|
|
116
|
+
}
|
|
117
|
+
|
|
71
118
|
next(): IteratorResult<[K, V]> {
|
|
72
119
|
const map = this.map;
|
|
120
|
+
if (!map) return IteratorResult.done<[K, V]>();
|
|
121
|
+
// Apply every missed compaction or clear before accessing the current entries buffer.
|
|
122
|
+
const currentVersion = map[GET_ITERATOR_VERSION]();
|
|
123
|
+
let version = assert(this.version);
|
|
124
|
+
while (version != currentVersion) {
|
|
125
|
+
this.i = version.translateIndex(this.i);
|
|
126
|
+
version = version.getNext();
|
|
127
|
+
}
|
|
128
|
+
this.version = version;
|
|
129
|
+
|
|
73
130
|
const start = map[GET_START]();
|
|
74
131
|
const size = map[GET_ENTRIES_OFFSET]();
|
|
75
132
|
for (let i = this.i; i < size; ++i) {
|
|
@@ -79,6 +136,10 @@ class MapIterator<K, V> implements Iterator<[K, V]> {
|
|
|
79
136
|
return IteratorResult.fromValue<[K, V]>([entry.key, entry.value]);
|
|
80
137
|
}
|
|
81
138
|
}
|
|
139
|
+
// Once done, later insertions must not revive this iterator.
|
|
140
|
+
// Release the map and any layout history still retained by this iterator.
|
|
141
|
+
this.map = null;
|
|
142
|
+
this.version = null;
|
|
82
143
|
return IteratorResult.done<[K, V]>();
|
|
83
144
|
}
|
|
84
145
|
}
|
|
@@ -93,6 +154,8 @@ export class Map<K, V> implements Iterable<[K, V]> {
|
|
|
93
154
|
private entriesCapacity: i32 = INITIAL_CAPACITY;
|
|
94
155
|
private entriesOffset: i32 = 0;
|
|
95
156
|
private entriesCount: i32 = 0;
|
|
157
|
+
// Lazy state: maps that never create iterators need no layout-change history.
|
|
158
|
+
private iteratorVersion: MapIteratorVersion | null = null;
|
|
96
159
|
|
|
97
160
|
constructor() {
|
|
98
161
|
/* nop */
|
|
@@ -107,6 +170,12 @@ export class Map<K, V> implements Iterable<[K, V]> {
|
|
|
107
170
|
[GET_ENTRIES_OFFSET](): i32 {
|
|
108
171
|
return this.entriesOffset;
|
|
109
172
|
}
|
|
173
|
+
@inline
|
|
174
|
+
[GET_ITERATOR_VERSION](): MapIteratorVersion {
|
|
175
|
+
let iteratorVersion = this.iteratorVersion;
|
|
176
|
+
if (!iteratorVersion) this.iteratorVersion = iteratorVersion = new MapIteratorVersion();
|
|
177
|
+
return iteratorVersion;
|
|
178
|
+
}
|
|
110
179
|
|
|
111
180
|
get size(): i32 {
|
|
112
181
|
return this.entriesCount;
|
|
@@ -116,6 +185,9 @@ export class Map<K, V> implements Iterable<[K, V]> {
|
|
|
116
185
|
this.buckets = new ArrayBuffer(INITIAL_CAPACITY * <i32>BUCKET_SIZE);
|
|
117
186
|
this.bucketsMask = INITIAL_CAPACITY - 1;
|
|
118
187
|
this.entries = new ArrayBuffer(INITIAL_CAPACITY * <i32>ENTRY_SIZE<K, V>());
|
|
188
|
+
// Live iterators must restart at entries inserted after clear(), rather than keep their old indices.
|
|
189
|
+
let iteratorVersion = this.iteratorVersion;
|
|
190
|
+
if (iteratorVersion) this.iteratorVersion = iteratorVersion.transition(null);
|
|
119
191
|
this.entriesCapacity = INITIAL_CAPACITY;
|
|
120
192
|
this.entriesOffset = 0;
|
|
121
193
|
this.entriesCount = 0;
|
|
@@ -206,9 +278,17 @@ export class Map<K, V> implements Iterable<[K, V]> {
|
|
|
206
278
|
let newEntries = new ArrayBuffer(newEntriesCapacity * <i32>ENTRY_SIZE<K, V>());
|
|
207
279
|
|
|
208
280
|
// copy old entries to new entries
|
|
209
|
-
let
|
|
281
|
+
let oldStart = changetype<usize>(this.entries);
|
|
282
|
+
let oldPtr = oldStart;
|
|
210
283
|
let oldEnd = oldPtr + <usize>this.entriesOffset * ENTRY_SIZE<K, V>();
|
|
211
284
|
let newPtr = changetype<usize>(newEntries);
|
|
285
|
+
let iteratorVersion = this.iteratorVersion;
|
|
286
|
+
// Record deleted slots only if iterator state exists; growth without holes leaves indices unchanged.
|
|
287
|
+
let removedIndices: StaticArray<i32> | null =
|
|
288
|
+
iteratorVersion && this.entriesOffset != this.entriesCount
|
|
289
|
+
? new StaticArray<i32>(this.entriesOffset - this.entriesCount)
|
|
290
|
+
: null;
|
|
291
|
+
let removedCount = 0;
|
|
212
292
|
while (oldPtr != oldEnd) {
|
|
213
293
|
let oldEntry = changetype<MapEntry<K, V>>(oldPtr);
|
|
214
294
|
if (!(oldEntry.taggedNext & EMPTY)) {
|
|
@@ -221,6 +301,9 @@ export class Map<K, V> implements Iterable<[K, V]> {
|
|
|
221
301
|
newEntry.taggedNext = load<usize>(newBucketPtrBase);
|
|
222
302
|
store<usize>(newBucketPtrBase, newPtr);
|
|
223
303
|
newPtr += ENTRY_SIZE<K, V>();
|
|
304
|
+
} else if (removedIndices) {
|
|
305
|
+
// Old slots are scanned in order, keeping the indices sorted for the lower-bound search.
|
|
306
|
+
unchecked((removedIndices[removedCount++] = <i32>((oldPtr - oldStart) / ENTRY_SIZE<K, V>())));
|
|
224
307
|
}
|
|
225
308
|
oldPtr += ENTRY_SIZE<K, V>();
|
|
226
309
|
}
|
|
@@ -228,6 +311,7 @@ export class Map<K, V> implements Iterable<[K, V]> {
|
|
|
228
311
|
this.buckets = newBuckets;
|
|
229
312
|
this.bucketsMask = newBucketsMask;
|
|
230
313
|
this.entries = newEntries;
|
|
314
|
+
if (iteratorVersion && removedIndices) this.iteratorVersion = iteratorVersion.transition(removedIndices);
|
|
231
315
|
this.entriesCapacity = newEntriesCapacity;
|
|
232
316
|
this.entriesOffset = this.entriesCount;
|
|
233
317
|
}
|
|
@@ -276,6 +360,9 @@ export class Map<K, V> implements Iterable<[K, V]> {
|
|
|
276
360
|
|
|
277
361
|
@unsafe private __visit(cookie: u32): void {
|
|
278
362
|
__visit(changetype<usize>(this.buckets), cookie);
|
|
363
|
+
// Map uses a custom visitor, so its managed iterator-version field must be traced explicitly.
|
|
364
|
+
let iteratorVersion = this.iteratorVersion;
|
|
365
|
+
if (iteratorVersion) __visit(changetype<usize>(iteratorVersion), cookie);
|
|
279
366
|
let entries = changetype<usize>(this.entries);
|
|
280
367
|
if (isManaged<K>() || isManaged<V>()) {
|
|
281
368
|
let cur = entries;
|
package/create/resolveModule.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import * as api from "./__warpo_create";
|
|
5
|
+
import { memory_expose } from "warpo/memory";
|
|
5
6
|
|
|
6
7
|
export class ModuleResolve {
|
|
7
8
|
packageName!: string;
|
|
@@ -13,5 +14,6 @@ export class ModuleResolve {
|
|
|
13
14
|
|
|
14
15
|
export type Fn = (task: ModuleResolve) => void;
|
|
15
16
|
export function onModuleResolve(fn: Fn): void {
|
|
17
|
+
memory_expose<ModuleResolve>();
|
|
16
18
|
api.onModuleResolve(fn.index, idof<ModuleResolve>());
|
|
17
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../../tools/test_runner/core/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,sBAAsB,CAAC;AAG9C,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAAY,YAAgC;QAC1C,KAAK,CAAC,YAAY,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,KAAK,UAAU,cAAc,CAAC,EAC5B,OAAO,EACP,MAAM,EACN,gBAAgB,EAChB,eAAe,GACG;IAClB,IAAI,SAAS,GAAG;QACd,GAAG,OAAO;QACV,IAAI;QACJ,MAAM,CAAC,IAAI;QACX,eAAe;QACf,wDAAwD;QACxD,eAAe;QACf,mBAAmB;QACnB,SAAS;QACT,kBAAkB;QAClB,WAAW;QACX,wBAAwB;QACxB,cAAc;KACf,CAAC;IACF,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,SAAS,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,2CAA2C;QAC3C,iCAAiC;QACjC,8EAA8E;QAC9E,gDAAgD;QAChD,MAAM,IAAI,GAAG,gBAAgB;aAC1B,OAAO,CAAC,WAAW,EAAE,mBAAmB,CAAC;aACzC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC;aACpC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;aAC9B,KAAK,CAAC,GAAG,CAAC,CAAC;QACd,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC;QACnC,IAAI,EAAE,SAAS;KAChB,CAAC,CAAC;IACH,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAyB;IACzD,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../../tools/test_runner/core/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,sBAAsB,CAAC;AAG9C,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAAY,YAAgC;QAC1C,KAAK,CAAC,YAAY,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,KAAK,UAAU,cAAc,CAAC,EAC5B,OAAO,EACP,MAAM,EACN,gBAAgB,EAChB,eAAe,GACG;IAClB,IAAI,SAAS,GAAG;QACd,GAAG,OAAO;QACV,IAAI;QACJ,MAAM,CAAC,IAAI;QACX,eAAe;QACf,wDAAwD;QACxD,eAAe;QACf,mBAAmB;QACnB,SAAS;QACT,kBAAkB;QAClB,WAAW;QACX,cAAc;QACd,wBAAwB;QACxB,cAAc;KACf,CAAC;IACF,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,SAAS,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,2CAA2C;QAC3C,iCAAiC;QACjC,8EAA8E;QAC9E,gDAAgD;QAChD,MAAM,IAAI,GAAG,gBAAgB;aAC1B,OAAO,CAAC,WAAW,EAAE,mBAAmB,CAAC;aACzC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC;aACpC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;aAC9B,KAAK,CAAC,GAAG,CAAC,CAAC;QACd,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC;QACnC,IAAI,EAAE,SAAS;KAChB,CAAC,CAAC;IACH,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAyB;IACzD,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|
package/package.json
CHANGED
package/types/warpo/index.d.ts
CHANGED