ember-source 5.6.0-alpha.2 → 5.6.0-alpha.3
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/build-metadata.json +3 -3
- package/dist/dependencies/@glimmer/debug.js +1533 -0
- package/dist/dependencies/@glimmer/destroyable.js +30 -59
- package/dist/dependencies/@glimmer/encoder.js +13 -24
- package/dist/dependencies/@glimmer/global-context.js +38 -41
- package/dist/dependencies/@glimmer/manager.js +144 -326
- package/dist/dependencies/@glimmer/node.js +14 -46
- package/dist/dependencies/@glimmer/opcode-compiler.js +1673 -2478
- package/dist/dependencies/@glimmer/owner.js +2 -5
- package/dist/dependencies/@glimmer/program.js +102 -185
- package/dist/dependencies/@glimmer/reference.js +58 -126
- package/dist/dependencies/@glimmer/runtime.js +4674 -5639
- package/dist/dependencies/@glimmer/util.js +340 -326
- package/dist/dependencies/@glimmer/validator.js +160 -217
- package/dist/dependencies/@glimmer/vm.js +174 -23
- package/dist/dependencies/@glimmer/wire-format.js +91 -34
- package/dist/dependencies/@simple-dom/document.js +1 -1
- package/dist/dependencies/router_js.js +15 -16
- package/dist/dependencies/rsvp.js +89 -88
- package/dist/ember-template-compiler.js +8574 -8350
- package/dist/ember-template-compiler.map +1 -1
- package/dist/ember-testing.js +107 -107
- package/dist/ember-testing.map +1 -1
- package/dist/ember.debug.js +11199 -9636
- package/dist/ember.debug.map +1 -1
- package/dist/header/license.js +1 -1
- package/dist/packages/@ember/-internals/glimmer/index.js +93 -83
- package/dist/packages/@ember/-internals/metal/index.js +5 -4
- package/dist/packages/@ember/-internals/utils/index.js +3 -4
- package/dist/packages/@ember/array/-internals.js +1 -2
- package/dist/packages/@ember/debug/lib/inspect.js +0 -1
- package/dist/packages/@ember/object/core.js +0 -1
- package/dist/packages/@ember/object/mixin.js +1 -2
- package/dist/packages/@ember/routing/route.js +23 -101
- package/dist/packages/@ember/routing/router.js +25 -84
- package/dist/packages/ember/version.js +1 -1
- package/dist/packages/ember-babel.js +13 -0
- package/docs/data.json +218 -243
- package/lib/index.js +1 -5
- package/package.json +24 -19
- package/types/stable/@ember/-internals/glimmer/index.d.ts +1 -1
- package/types/stable/@ember/-internals/glimmer/lib/component-managers/curly.d.ts +4 -4
- package/types/stable/@ember/-internals/glimmer/lib/component-managers/mount.d.ts +3 -3
- package/types/stable/@ember/-internals/glimmer/lib/component-managers/outlet.d.ts +5 -8
- package/types/stable/@ember/-internals/glimmer/lib/component-managers/root.d.ts +3 -3
- package/types/stable/@ember/-internals/glimmer/lib/renderer.d.ts +3 -3
- package/types/stable/@ember/-internals/glimmer/lib/resolver.d.ts +3 -3
- package/types/stable/@ember/-internals/glimmer/lib/syntax/utils.d.ts +3 -2
- package/types/stable/@ember/-internals/glimmer/lib/utils/iterator.d.ts +2 -2
- package/types/stable/@ember/-internals/glimmer/lib/utils/outlet.d.ts +39 -18
- package/types/stable/@ember/-internals/utility-types/index.d.ts +1 -0
- package/types/stable/@ember/-internals/views/lib/system/utils.d.ts +4 -3
- package/types/stable/@ember/routing/route.d.ts +6 -28
- package/dist/dependencies/@glimmer/low-level.js +0 -77
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const OWNER = symbol('OWNER');
|
|
1
|
+
const OWNER = Symbol('OWNER');
|
|
4
2
|
/**
|
|
5
3
|
Framework objects in a Glimmer application may receive an owner object.
|
|
6
4
|
Glimmer is unopinionated about this owner, but will forward it through its
|
|
7
5
|
internal resolution system, and through its managers if it is provided.
|
|
8
6
|
*/
|
|
9
|
-
|
|
10
7
|
function getOwner(object) {
|
|
11
8
|
return object[OWNER];
|
|
12
9
|
}
|
|
10
|
+
|
|
13
11
|
/**
|
|
14
12
|
`setOwner` set's an object's owner
|
|
15
13
|
*/
|
|
16
|
-
|
|
17
14
|
function setOwner(object, owner) {
|
|
18
15
|
object[OWNER] = owner;
|
|
19
16
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { constants, unwrapTemplate } from '@glimmer/util';
|
|
2
1
|
import { getInternalHelperManager, getInternalModifierManager, getInternalComponentManager, capabilityFlagsFrom, getComponentTemplate, managerHasCapability } from '@glimmer/manager';
|
|
3
2
|
import { templateFactory } from '@glimmer/opcode-compiler';
|
|
3
|
+
import { constants, enumerate, assert, unwrapTemplate, expect, unwrap } from '@glimmer/util';
|
|
4
|
+
import { InternalComponentCapabilities, OPERAND_LEN_MASK, ARG_SHIFT, MACHINE_MASK, TYPE_MASK } from '@glimmer/vm';
|
|
5
|
+
import { SexpOpcodes } from '@glimmer/wire-format';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Default component template, which is a plain yield
|
|
7
9
|
*/
|
|
8
|
-
const DEFAULT_TEMPLATE_BLOCK = [[[
|
|
9
|
-
/* Yield */
|
|
10
|
-
, 1, null]], ['&default'], false, []];
|
|
10
|
+
const DEFAULT_TEMPLATE_BLOCK = [[[SexpOpcodes.Yield, 1, null]], ['&default'], false, []];
|
|
11
11
|
const DEFAULT_TEMPLATE = {
|
|
12
12
|
// random uuid
|
|
13
13
|
id: '1b32f5c2-7623-43d6-a0ad-9672898920a1',
|
|
@@ -21,113 +21,91 @@ const WELL_KNOWN_EMPTY_ARRAY = Object.freeze([]);
|
|
|
21
21
|
const STARTER_CONSTANTS = constants(WELL_KNOWN_EMPTY_ARRAY);
|
|
22
22
|
const WELL_KNOWN_EMPTY_ARRAY_POSITION = STARTER_CONSTANTS.indexOf(WELL_KNOWN_EMPTY_ARRAY);
|
|
23
23
|
class CompileTimeConstantImpl {
|
|
24
|
-
|
|
25
|
-
// `0` means NULL
|
|
26
|
-
this.values = STARTER_CONSTANTS.slice();
|
|
27
|
-
this.indexMap = new Map(this.values.map((value, index) => [value, index]));
|
|
28
|
-
}
|
|
24
|
+
// `0` means NULL
|
|
29
25
|
|
|
26
|
+
values = STARTER_CONSTANTS.slice();
|
|
27
|
+
indexMap = new Map(this.values.map((value, index) => [value, index]));
|
|
30
28
|
value(value) {
|
|
31
29
|
let indexMap = this.indexMap;
|
|
32
30
|
let index = indexMap.get(value);
|
|
33
|
-
|
|
34
31
|
if (index === undefined) {
|
|
35
32
|
index = this.values.push(value) - 1;
|
|
36
33
|
indexMap.set(value, index);
|
|
37
34
|
}
|
|
38
|
-
|
|
39
35
|
return index;
|
|
40
36
|
}
|
|
41
|
-
|
|
42
37
|
array(values) {
|
|
43
38
|
if (values.length === 0) {
|
|
44
39
|
return WELL_KNOWN_EMPTY_ARRAY_POSITION;
|
|
45
40
|
}
|
|
46
|
-
|
|
47
41
|
let handles = new Array(values.length);
|
|
48
|
-
|
|
49
42
|
for (let i = 0; i < values.length; i++) {
|
|
50
43
|
handles[i] = this.value(values[i]);
|
|
51
44
|
}
|
|
52
|
-
|
|
53
45
|
return this.value(handles);
|
|
54
46
|
}
|
|
55
|
-
|
|
56
47
|
toPool() {
|
|
57
48
|
return this.values;
|
|
58
49
|
}
|
|
59
|
-
|
|
60
50
|
}
|
|
61
51
|
class RuntimeConstantsImpl {
|
|
52
|
+
values;
|
|
62
53
|
constructor(pool) {
|
|
63
54
|
this.values = pool;
|
|
64
55
|
}
|
|
65
|
-
|
|
66
56
|
getValue(handle) {
|
|
67
57
|
return this.values[handle];
|
|
68
58
|
}
|
|
69
|
-
|
|
70
59
|
getArray(value) {
|
|
71
60
|
let handles = this.getValue(value);
|
|
72
61
|
let reified = new Array(handles.length);
|
|
73
|
-
|
|
74
|
-
for (let i = 0; i < handles.length; i++) {
|
|
75
|
-
let n = handles[i];
|
|
62
|
+
for (const [i, n] of enumerate(handles)) {
|
|
76
63
|
reified[i] = this.getValue(n);
|
|
77
64
|
}
|
|
78
|
-
|
|
79
65
|
return reified;
|
|
80
66
|
}
|
|
81
|
-
|
|
82
67
|
}
|
|
83
68
|
class ConstantsImpl extends CompileTimeConstantImpl {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
helper(definitionState, // TODO: Add a way to expose resolved name for debugging
|
|
101
|
-
_resolvedName = null, isOptional) {
|
|
69
|
+
reifiedArrs = {
|
|
70
|
+
[WELL_KNOWN_EMPTY_ARRAY_POSITION]: WELL_KNOWN_EMPTY_ARRAY
|
|
71
|
+
};
|
|
72
|
+
defaultTemplate = templateFactory(DEFAULT_TEMPLATE)();
|
|
73
|
+
|
|
74
|
+
// Used for tests and debugging purposes, and to be able to analyze large apps
|
|
75
|
+
// This is why it's enabled even in production
|
|
76
|
+
helperDefinitionCount = 0;
|
|
77
|
+
modifierDefinitionCount = 0;
|
|
78
|
+
componentDefinitionCount = 0;
|
|
79
|
+
helperDefinitionCache = new WeakMap();
|
|
80
|
+
modifierDefinitionCache = new WeakMap();
|
|
81
|
+
componentDefinitionCache = new WeakMap();
|
|
82
|
+
helper(definitionState) {
|
|
83
|
+
let isOptional = arguments.length > 2 ? arguments[2] : undefined;
|
|
102
84
|
let handle = this.helperDefinitionCache.get(definitionState);
|
|
103
|
-
|
|
104
85
|
if (handle === undefined) {
|
|
105
86
|
let managerOrHelper = getInternalHelperManager(definitionState, isOptional);
|
|
106
|
-
|
|
107
87
|
if (managerOrHelper === null) {
|
|
108
88
|
this.helperDefinitionCache.set(definitionState, null);
|
|
109
89
|
return null;
|
|
110
90
|
}
|
|
91
|
+
assert(managerOrHelper, 'BUG: expected manager or helper');
|
|
111
92
|
let helper = typeof managerOrHelper === 'function' ? managerOrHelper : managerOrHelper.getHelper(definitionState);
|
|
112
93
|
handle = this.value(helper);
|
|
113
94
|
this.helperDefinitionCache.set(definitionState, handle);
|
|
114
95
|
this.helperDefinitionCount++;
|
|
115
96
|
}
|
|
116
|
-
|
|
117
97
|
return handle;
|
|
118
98
|
}
|
|
119
|
-
|
|
120
|
-
|
|
99
|
+
modifier(definitionState) {
|
|
100
|
+
let resolvedName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
101
|
+
let isOptional = arguments.length > 2 ? arguments[2] : undefined;
|
|
121
102
|
let handle = this.modifierDefinitionCache.get(definitionState);
|
|
122
|
-
|
|
123
103
|
if (handle === undefined) {
|
|
124
104
|
let manager = getInternalModifierManager(definitionState, isOptional);
|
|
125
|
-
|
|
126
105
|
if (manager === null) {
|
|
127
106
|
this.modifierDefinitionCache.set(definitionState, null);
|
|
128
107
|
return null;
|
|
129
108
|
}
|
|
130
|
-
|
|
131
109
|
let definition = {
|
|
132
110
|
resolvedName,
|
|
133
111
|
manager,
|
|
@@ -137,45 +115,34 @@ class ConstantsImpl extends CompileTimeConstantImpl {
|
|
|
137
115
|
this.modifierDefinitionCache.set(definitionState, handle);
|
|
138
116
|
this.modifierDefinitionCount++;
|
|
139
117
|
}
|
|
140
|
-
|
|
141
118
|
return handle;
|
|
142
119
|
}
|
|
143
|
-
|
|
144
120
|
component(definitionState, owner, isOptional) {
|
|
145
|
-
var _a;
|
|
146
|
-
|
|
147
121
|
let definition = this.componentDefinitionCache.get(definitionState);
|
|
148
|
-
|
|
149
122
|
if (definition === undefined) {
|
|
150
123
|
let manager = getInternalComponentManager(definitionState, isOptional);
|
|
151
|
-
|
|
152
124
|
if (manager === null) {
|
|
153
125
|
this.componentDefinitionCache.set(definitionState, null);
|
|
154
126
|
return null;
|
|
155
127
|
}
|
|
128
|
+
assert(manager, 'BUG: expected manager');
|
|
156
129
|
let capabilities = capabilityFlagsFrom(manager.getCapabilities(definitionState));
|
|
157
130
|
let templateFactory = getComponentTemplate(definitionState);
|
|
158
131
|
let compilable = null;
|
|
159
132
|
let template;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
/* DynamicLayout */
|
|
163
|
-
)) {
|
|
164
|
-
template = (_a = templateFactory === null || templateFactory === void 0 ? void 0 : templateFactory(owner)) !== null && _a !== void 0 ? _a : this.defaultTemplate;
|
|
133
|
+
if (!managerHasCapability(manager, capabilities, InternalComponentCapabilities.dynamicLayout)) {
|
|
134
|
+
template = templateFactory?.(owner) ?? this.defaultTemplate;
|
|
165
135
|
} else {
|
|
166
|
-
template = templateFactory
|
|
136
|
+
template = templateFactory?.(owner);
|
|
167
137
|
}
|
|
168
|
-
|
|
169
138
|
if (template !== undefined) {
|
|
170
139
|
template = unwrapTemplate(template);
|
|
171
|
-
compilable = managerHasCapability(manager, capabilities,
|
|
172
|
-
/* Wrapped */
|
|
173
|
-
) ? template.asWrappedLayout() : template.asLayout();
|
|
140
|
+
compilable = managerHasCapability(manager, capabilities, InternalComponentCapabilities.wrapped) ? template.asWrappedLayout() : template.asLayout();
|
|
174
141
|
}
|
|
175
|
-
|
|
176
142
|
definition = {
|
|
177
143
|
resolvedName: null,
|
|
178
144
|
handle: -1,
|
|
145
|
+
// replaced momentarily
|
|
179
146
|
manager,
|
|
180
147
|
capabilities,
|
|
181
148
|
state: definitionState,
|
|
@@ -185,13 +152,10 @@ class ConstantsImpl extends CompileTimeConstantImpl {
|
|
|
185
152
|
this.componentDefinitionCache.set(definitionState, definition);
|
|
186
153
|
this.componentDefinitionCount++;
|
|
187
154
|
}
|
|
188
|
-
|
|
189
155
|
return definition;
|
|
190
156
|
}
|
|
191
|
-
|
|
192
157
|
resolvedComponent(resolvedDefinition, resolvedName) {
|
|
193
158
|
let definition = this.componentDefinitionCache.get(resolvedDefinition);
|
|
194
|
-
|
|
195
159
|
if (definition === undefined) {
|
|
196
160
|
let {
|
|
197
161
|
manager,
|
|
@@ -200,23 +164,17 @@ class ConstantsImpl extends CompileTimeConstantImpl {
|
|
|
200
164
|
} = resolvedDefinition;
|
|
201
165
|
let capabilities = capabilityFlagsFrom(manager.getCapabilities(resolvedDefinition));
|
|
202
166
|
let compilable = null;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
/* DynamicLayout */
|
|
206
|
-
)) {
|
|
207
|
-
template = template !== null && template !== void 0 ? template : this.defaultTemplate;
|
|
167
|
+
if (!managerHasCapability(manager, capabilities, InternalComponentCapabilities.dynamicLayout)) {
|
|
168
|
+
template = template ?? this.defaultTemplate;
|
|
208
169
|
}
|
|
209
|
-
|
|
210
170
|
if (template !== null) {
|
|
211
171
|
template = unwrapTemplate(template);
|
|
212
|
-
compilable = managerHasCapability(manager, capabilities,
|
|
213
|
-
/* Wrapped */
|
|
214
|
-
) ? template.asWrappedLayout() : template.asLayout();
|
|
172
|
+
compilable = managerHasCapability(manager, capabilities, InternalComponentCapabilities.wrapped) ? template.asWrappedLayout() : template.asLayout();
|
|
215
173
|
}
|
|
216
|
-
|
|
217
174
|
definition = {
|
|
218
175
|
resolvedName,
|
|
219
176
|
handle: -1,
|
|
177
|
+
// replaced momentarily
|
|
220
178
|
manager,
|
|
221
179
|
capabilities,
|
|
222
180
|
state,
|
|
@@ -226,78 +184,65 @@ class ConstantsImpl extends CompileTimeConstantImpl {
|
|
|
226
184
|
this.componentDefinitionCache.set(resolvedDefinition, definition);
|
|
227
185
|
this.componentDefinitionCount++;
|
|
228
186
|
}
|
|
229
|
-
|
|
230
|
-
return definition;
|
|
187
|
+
return expect(definition, 'BUG: resolved component definitions cannot be null');
|
|
231
188
|
}
|
|
232
|
-
|
|
233
189
|
getValue(index) {
|
|
190
|
+
assert(index >= 0, `cannot get value for handle: ${index}`);
|
|
234
191
|
return this.values[index];
|
|
235
192
|
}
|
|
236
|
-
|
|
237
193
|
getArray(index) {
|
|
238
194
|
let reifiedArrs = this.reifiedArrs;
|
|
239
195
|
let reified = reifiedArrs[index];
|
|
240
|
-
|
|
241
196
|
if (reified === undefined) {
|
|
242
197
|
let names = this.getValue(index);
|
|
243
198
|
reified = new Array(names.length);
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
reified[i] = this.getValue(names[i]);
|
|
199
|
+
for (const [i, name] of enumerate(names)) {
|
|
200
|
+
reified[i] = this.getValue(name);
|
|
247
201
|
}
|
|
248
|
-
|
|
249
202
|
reifiedArrs[index] = reified;
|
|
250
203
|
}
|
|
251
|
-
|
|
252
204
|
return reified;
|
|
253
205
|
}
|
|
254
|
-
|
|
255
206
|
}
|
|
256
207
|
|
|
257
208
|
class RuntimeOpImpl {
|
|
209
|
+
offset = 0;
|
|
258
210
|
constructor(heap) {
|
|
259
211
|
this.heap = heap;
|
|
260
|
-
this.offset = 0;
|
|
261
212
|
}
|
|
262
|
-
|
|
263
213
|
get size() {
|
|
264
214
|
let rawType = this.heap.getbyaddr(this.offset);
|
|
265
|
-
return ((rawType &
|
|
266
|
-
/* OPERAND_LEN_MASK */
|
|
267
|
-
) >> 8
|
|
268
|
-
/* ARG_SHIFT */
|
|
269
|
-
) + 1;
|
|
215
|
+
return ((rawType & OPERAND_LEN_MASK) >> ARG_SHIFT) + 1;
|
|
270
216
|
}
|
|
271
|
-
|
|
272
217
|
get isMachine() {
|
|
273
218
|
let rawType = this.heap.getbyaddr(this.offset);
|
|
274
|
-
return rawType &
|
|
275
|
-
/* MACHINE_MASK */
|
|
276
|
-
? 1 : 0;
|
|
219
|
+
return rawType & MACHINE_MASK ? 1 : 0;
|
|
277
220
|
}
|
|
278
|
-
|
|
279
221
|
get type() {
|
|
280
|
-
return this.heap.getbyaddr(this.offset) &
|
|
281
|
-
/* TYPE_MASK */
|
|
282
|
-
;
|
|
222
|
+
return this.heap.getbyaddr(this.offset) & TYPE_MASK;
|
|
283
223
|
}
|
|
284
|
-
|
|
285
224
|
get op1() {
|
|
286
225
|
return this.heap.getbyaddr(this.offset + 1);
|
|
287
226
|
}
|
|
288
|
-
|
|
289
227
|
get op2() {
|
|
290
228
|
return this.heap.getbyaddr(this.offset + 2);
|
|
291
229
|
}
|
|
292
|
-
|
|
293
230
|
get op3() {
|
|
294
231
|
return this.heap.getbyaddr(this.offset + 3);
|
|
295
232
|
}
|
|
296
|
-
|
|
297
233
|
}
|
|
298
234
|
|
|
235
|
+
var TableSlotState = /*#__PURE__*/function (TableSlotState) {
|
|
236
|
+
TableSlotState[TableSlotState["Allocated"] = 0] = "Allocated";
|
|
237
|
+
TableSlotState[TableSlotState["Freed"] = 1] = "Freed";
|
|
238
|
+
TableSlotState[TableSlotState["Purged"] = 2] = "Purged";
|
|
239
|
+
TableSlotState[TableSlotState["Pointer"] = 3] = "Pointer";
|
|
240
|
+
return TableSlotState;
|
|
241
|
+
}(TableSlotState || {});
|
|
299
242
|
const PAGE_SIZE = 0x100000;
|
|
300
243
|
class RuntimeHeapImpl {
|
|
244
|
+
heap;
|
|
245
|
+
table;
|
|
301
246
|
constructor(serializedHeap) {
|
|
302
247
|
let {
|
|
303
248
|
buffer,
|
|
@@ -305,27 +250,25 @@ class RuntimeHeapImpl {
|
|
|
305
250
|
} = serializedHeap;
|
|
306
251
|
this.heap = new Int32Array(buffer);
|
|
307
252
|
this.table = table;
|
|
308
|
-
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// It is illegal to close over this address, as compaction
|
|
309
256
|
// may move it. However, it is legal to use this address
|
|
310
257
|
// multiple times between compactions.
|
|
311
|
-
|
|
312
|
-
|
|
313
258
|
getaddr(handle) {
|
|
314
|
-
return this.table[handle];
|
|
259
|
+
return unwrap(this.table[handle]);
|
|
315
260
|
}
|
|
316
|
-
|
|
317
261
|
getbyaddr(address) {
|
|
318
|
-
return this.heap[address];
|
|
262
|
+
return expect(this.heap[address], 'Access memory out of bounds of the heap');
|
|
319
263
|
}
|
|
320
|
-
|
|
321
264
|
sizeof(handle) {
|
|
322
265
|
return sizeof(this.table);
|
|
323
266
|
}
|
|
324
|
-
|
|
325
267
|
}
|
|
326
268
|
function hydrateHeap(serializedHeap) {
|
|
327
269
|
return new RuntimeHeapImpl(serializedHeap);
|
|
328
270
|
}
|
|
271
|
+
|
|
329
272
|
/**
|
|
330
273
|
* The Heap is responsible for dynamically allocating
|
|
331
274
|
* memory in which we read/write the VM's instructions
|
|
@@ -346,70 +289,67 @@ function hydrateHeap(serializedHeap) {
|
|
|
346
289
|
* valid during the execution. This means you cannot close
|
|
347
290
|
* over them as you will have a bad memory access exception.
|
|
348
291
|
*/
|
|
349
|
-
|
|
350
292
|
class HeapImpl {
|
|
293
|
+
offset = 0;
|
|
294
|
+
heap;
|
|
295
|
+
handleTable;
|
|
296
|
+
handleState;
|
|
297
|
+
handle = 0;
|
|
351
298
|
constructor() {
|
|
352
|
-
this.offset = 0;
|
|
353
|
-
this.handle = 0;
|
|
354
299
|
this.heap = new Int32Array(PAGE_SIZE);
|
|
355
300
|
this.handleTable = [];
|
|
356
301
|
this.handleState = [];
|
|
357
302
|
}
|
|
358
|
-
|
|
359
|
-
push(item) {
|
|
303
|
+
pushRaw(value) {
|
|
360
304
|
this.sizeCheck();
|
|
361
|
-
this.heap[this.offset++] =
|
|
305
|
+
this.heap[this.offset++] = value;
|
|
306
|
+
}
|
|
307
|
+
pushOp(item) {
|
|
308
|
+
this.pushRaw(item);
|
|
309
|
+
}
|
|
310
|
+
pushMachine(item) {
|
|
311
|
+
this.pushRaw(item | MACHINE_MASK);
|
|
362
312
|
}
|
|
363
|
-
|
|
364
313
|
sizeCheck() {
|
|
365
314
|
let {
|
|
366
315
|
heap
|
|
367
316
|
} = this;
|
|
368
|
-
|
|
369
317
|
if (this.offset === this.heap.length) {
|
|
370
318
|
let newHeap = new Int32Array(heap.length + PAGE_SIZE);
|
|
371
319
|
newHeap.set(heap, 0);
|
|
372
320
|
this.heap = newHeap;
|
|
373
321
|
}
|
|
374
322
|
}
|
|
375
|
-
|
|
376
323
|
getbyaddr(address) {
|
|
377
|
-
return this.heap[address];
|
|
324
|
+
return unwrap(this.heap[address]);
|
|
378
325
|
}
|
|
379
|
-
|
|
380
326
|
setbyaddr(address, value) {
|
|
381
327
|
this.heap[address] = value;
|
|
382
328
|
}
|
|
383
|
-
|
|
384
329
|
malloc() {
|
|
385
330
|
// push offset, info, size
|
|
386
331
|
this.handleTable.push(this.offset);
|
|
387
332
|
return this.handleTable.length - 1;
|
|
388
333
|
}
|
|
389
|
-
|
|
390
334
|
finishMalloc(handle) {
|
|
391
335
|
}
|
|
392
|
-
|
|
393
336
|
size() {
|
|
394
337
|
return this.offset;
|
|
395
|
-
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// It is illegal to close over this address, as compaction
|
|
396
341
|
// may move it. However, it is legal to use this address
|
|
397
342
|
// multiple times between compactions.
|
|
398
|
-
|
|
399
|
-
|
|
400
343
|
getaddr(handle) {
|
|
401
|
-
return this.handleTable[handle];
|
|
344
|
+
return unwrap(this.handleTable[handle]);
|
|
402
345
|
}
|
|
403
|
-
|
|
404
346
|
sizeof(handle) {
|
|
405
347
|
return sizeof(this.handleTable);
|
|
406
348
|
}
|
|
407
|
-
|
|
408
349
|
free(handle) {
|
|
409
|
-
this.handleState[handle] =
|
|
410
|
-
/* Freed */
|
|
411
|
-
;
|
|
350
|
+
this.handleState[handle] = TableSlotState.Freed;
|
|
412
351
|
}
|
|
352
|
+
|
|
413
353
|
/**
|
|
414
354
|
* The heap uses the [Mark-Compact Algorithm](https://en.wikipedia.org/wiki/Mark-compact_algorithm) to shift
|
|
415
355
|
* reachable memory to the bottom of the heap and freeable
|
|
@@ -417,8 +357,6 @@ class HeapImpl {
|
|
|
417
357
|
* the reachable memory to the top of the heap, we move the
|
|
418
358
|
* offset to the next free position.
|
|
419
359
|
*/
|
|
420
|
-
|
|
421
|
-
|
|
422
360
|
compact() {
|
|
423
361
|
let compactedSize = 0;
|
|
424
362
|
let {
|
|
@@ -426,45 +364,31 @@ class HeapImpl {
|
|
|
426
364
|
handleState,
|
|
427
365
|
heap
|
|
428
366
|
} = this;
|
|
429
|
-
|
|
430
367
|
for (let i = 0; i < length; i++) {
|
|
431
|
-
let offset = handleTable[i];
|
|
432
|
-
let size = handleTable[i + 1] - offset;
|
|
368
|
+
let offset = unwrap(handleTable[i]);
|
|
369
|
+
let size = unwrap(handleTable[i + 1]) - unwrap(offset);
|
|
433
370
|
let state = handleState[i];
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
handleState[i] = 2
|
|
446
|
-
/* Purged */
|
|
447
|
-
;
|
|
448
|
-
compactedSize += size;
|
|
449
|
-
} else if (state === 0
|
|
450
|
-
/* Allocated */
|
|
451
|
-
) {
|
|
452
|
-
for (let j = offset; j <= i + size; j++) {
|
|
453
|
-
heap[j - compactedSize] = heap[j];
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
handleTable[i] = offset - compactedSize;
|
|
457
|
-
} else if (state === 3
|
|
458
|
-
/* Pointer */
|
|
459
|
-
) {
|
|
460
|
-
handleTable[i] = offset - compactedSize;
|
|
371
|
+
if (state === TableSlotState.Purged) {
|
|
372
|
+
continue;
|
|
373
|
+
} else if (state === TableSlotState.Freed) {
|
|
374
|
+
// transition to "already freed" aka "purged"
|
|
375
|
+
// a good improvement would be to reuse
|
|
376
|
+
// these slots
|
|
377
|
+
handleState[i] = TableSlotState.Purged;
|
|
378
|
+
compactedSize += size;
|
|
379
|
+
} else if (state === TableSlotState.Allocated) {
|
|
380
|
+
for (let j = offset; j <= i + size; j++) {
|
|
381
|
+
heap[j - compactedSize] = unwrap(heap[j]);
|
|
461
382
|
}
|
|
383
|
+
handleTable[i] = offset - compactedSize;
|
|
384
|
+
} else if (state === TableSlotState.Pointer) {
|
|
385
|
+
handleTable[i] = offset - compactedSize;
|
|
386
|
+
}
|
|
462
387
|
}
|
|
463
|
-
|
|
464
388
|
this.offset = this.offset - compactedSize;
|
|
465
389
|
}
|
|
466
|
-
|
|
467
|
-
|
|
390
|
+
capture() {
|
|
391
|
+
let offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.offset;
|
|
468
392
|
// Only called in eager mode
|
|
469
393
|
let buffer = slice(this.heap, 0, offset).buffer;
|
|
470
394
|
return {
|
|
@@ -473,36 +397,29 @@ class HeapImpl {
|
|
|
473
397
|
buffer: buffer
|
|
474
398
|
};
|
|
475
399
|
}
|
|
476
|
-
|
|
477
400
|
}
|
|
478
401
|
class RuntimeProgramImpl {
|
|
402
|
+
_opcode;
|
|
479
403
|
constructor(constants, heap) {
|
|
480
404
|
this.constants = constants;
|
|
481
405
|
this.heap = heap;
|
|
482
406
|
this._opcode = new RuntimeOpImpl(this.heap);
|
|
483
407
|
}
|
|
484
|
-
|
|
485
408
|
opcode(offset) {
|
|
486
409
|
this._opcode.offset = offset;
|
|
487
410
|
return this._opcode;
|
|
488
411
|
}
|
|
489
|
-
|
|
490
412
|
}
|
|
491
|
-
|
|
492
413
|
function slice(arr, start, end) {
|
|
493
414
|
if (arr.slice !== undefined) {
|
|
494
415
|
return arr.slice(start, end);
|
|
495
416
|
}
|
|
496
|
-
|
|
497
417
|
let ret = new Int32Array(end);
|
|
498
|
-
|
|
499
418
|
for (; start < end; start++) {
|
|
500
|
-
ret[start] = arr[start];
|
|
419
|
+
ret[start] = unwrap(arr[start]);
|
|
501
420
|
}
|
|
502
|
-
|
|
503
421
|
return ret;
|
|
504
422
|
}
|
|
505
|
-
|
|
506
423
|
function sizeof(table, handle) {
|
|
507
424
|
{
|
|
508
425
|
return -1;
|