@engine262/engine262 0.0.1-093c8cb33fc82c295390da3d9e124c21ad7e6281

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.
@@ -0,0 +1,330 @@
1
+ 'use strict';
2
+
3
+ const engine262 = require('..');
4
+
5
+ const contexts = [];
6
+
7
+ class InspectorContext {
8
+ constructor(realm) {
9
+ this.realm = realm;
10
+ this.idToObject = new Map();
11
+ this.objectToId = new Map();
12
+ this.objectCounter = 0;
13
+ this.previewStack = [];
14
+ }
15
+
16
+ internObject(object, group = 'default') {
17
+ if (this.objectToId.has(object)) {
18
+ return this.objectToId.get(object);
19
+ }
20
+ const id = `${group}:${this.objectCounter}`;
21
+ this.objectCounter += 1;
22
+ this.idToObject.set(id, object);
23
+ this.objectToId.set(object, id);
24
+ return id;
25
+ }
26
+
27
+ releaseObjectGroup(group) {
28
+ for (const [id, object] of this.idToObject.entries()) {
29
+ if (id.startsWith(group)) {
30
+ this.idToObject.delete(id);
31
+ this.objectToId.delete(object);
32
+ }
33
+ }
34
+ }
35
+
36
+ getObject(objectId) {
37
+ return this.idToObject.get(objectId);
38
+ }
39
+
40
+ toRemoteObject(object, options) {
41
+ const result = {};
42
+ switch (engine262.Type(object)) {
43
+ case 'Object':
44
+ result.objectId = this.internObject(object, options.objectGroup);
45
+ if ('Call' in object) {
46
+ result.type = 'function';
47
+ } else {
48
+ result.type = 'object';
49
+ if ('PromiseState' in object) {
50
+ result.subtype = 'promise';
51
+ } else if ('MapData' in object) {
52
+ result.subtype = 'map';
53
+ } else if ('SetData' in object) {
54
+ result.subtype = 'set';
55
+ } else if ('ErrorData' in object) {
56
+ result.subtype = 'error';
57
+ } else if ('TypedArrayName' in object) {
58
+ result.subtype = 'typedarray';
59
+ } else if ('DataView' in object) {
60
+ result.subtype = 'dataview';
61
+ } else if ('ProxyTarget' in object) {
62
+ result.subtype = 'proxy';
63
+ } else if ('DateValue' in object) {
64
+ result.subtype = 'date';
65
+ } else if ('GeneratorState' in object) {
66
+ result.subtype = 'generator';
67
+ } else if (engine262.IsArray(object) === engine262.Value.true) {
68
+ result.subtype = 'array';
69
+ }
70
+ }
71
+ break;
72
+ case 'Null':
73
+ result.type = 'object';
74
+ result.subtype = 'null';
75
+ result.value = null;
76
+ break;
77
+ case 'Undefined':
78
+ result.type = 'undefined';
79
+ break;
80
+ case 'String':
81
+ result.type = 'string';
82
+ result.value = object.stringValue();
83
+ break;
84
+ case 'Number': {
85
+ result.type = 'number';
86
+ const v = object.numberValue();
87
+ if (!Number.isFinite(v)) {
88
+ result.unserializableValue = v.toString();
89
+ } else {
90
+ result.value = v;
91
+ }
92
+ break;
93
+ }
94
+ case 'Boolean':
95
+ result.type = 'boolean';
96
+ result.value = object.booleanValue();
97
+ break;
98
+ case 'BigInt':
99
+ result.type = 'bigint';
100
+ result.unserializableValue = `${object.bigintValue().toString()}n`;
101
+ break;
102
+ case 'Symbol':
103
+ result.type = 'symbol';
104
+ result.description = object.Description === engine262.Value.undefined
105
+ ? undefined
106
+ : object.Description.stringValue();
107
+ break;
108
+ default:
109
+ throw new RangeError();
110
+ }
111
+ if (options.generatePreview
112
+ && result.type === 'object'
113
+ && result.subtype !== 'null'
114
+ && !this.previewStack.includes(object)) {
115
+ this.previewStack.push(object);
116
+ const properties = this.getPropertyPreview(object, options);
117
+ let entries;
118
+ if ('MapData' in object) {
119
+ entries = object.MapData.map((d) => ({
120
+ key: this.toRemoteObject(d.Key, options).preview,
121
+ value: this.toRemoteObject(d.Value, options).preview,
122
+ }));
123
+ }
124
+ this.previewStack.pop();
125
+ result.preview = {
126
+ type: result.type,
127
+ subtype: result.subtype,
128
+ overflow: properties.length > 5,
129
+ properties: properties.slice(0, 5),
130
+ entries,
131
+ };
132
+ }
133
+ return result;
134
+ }
135
+
136
+ getProperties(object, options) {
137
+ const wrap = (v) => this.toRemoteObject(v, options);
138
+
139
+ const properties = [];
140
+ const internalProperties = [];
141
+
142
+ let p = object;
143
+ while (p !== engine262.Value.null) {
144
+ const keys = p.OwnPropertyKeys();
145
+ if (keys instanceof engine262.AbruptCompletion) {
146
+ return keys;
147
+ }
148
+
149
+ for (const key of keys) {
150
+ const desc = p.GetOwnProperty(key);
151
+ if (desc instanceof engine262.AbruptCompletion) {
152
+ return desc;
153
+ }
154
+ if (options.accessorPropertiesOnly && desc.Value) {
155
+ continue;
156
+ }
157
+ const descriptor = {
158
+ name: key.stringValue
159
+ ? key.stringValue()
160
+ : undefined,
161
+ value: desc.Value ? wrap(desc.Value) : undefined,
162
+ writable: desc.Writable === engine262.Value.true,
163
+ get: desc.Get ? wrap(desc.Get) : undefined,
164
+ set: desc.Set ? wrap(desc.Set) : undefined,
165
+ configurable: desc.Configurable === engine262.Value.true,
166
+ enumerable: desc.Enumerable === engine262.Value.true,
167
+ wasThrown: false,
168
+ isOwn: p === object,
169
+ symbol: key.stringValue ? undefined : wrap(key),
170
+ };
171
+ properties.push(descriptor);
172
+ }
173
+
174
+ if (options.ownProperties) {
175
+ break;
176
+ }
177
+ p = p.GetPrototypeOf();
178
+ if (p instanceof engine262.AbruptCompletion) {
179
+ return p;
180
+ }
181
+ }
182
+
183
+ if ('PromiseState' in object) {
184
+ internalProperties.push({
185
+ name: '[[PromiseState]]',
186
+ value: {
187
+ type: 'string',
188
+ value: object.PromiseState,
189
+ },
190
+ });
191
+ internalProperties.push({
192
+ name: '[[PromiseResult]]',
193
+ value: wrap(object.PromiseResult),
194
+ });
195
+ }
196
+
197
+ return { properties, internalProperties };
198
+ }
199
+
200
+ getPropertyPreview(object, options) {
201
+ const wrap = (v) => this.toRemoteObject(v, options);
202
+
203
+ const keys = object.OwnPropertyKeys();
204
+ if (keys instanceof engine262.AbruptCompletion) {
205
+ return keys;
206
+ }
207
+
208
+ const properties = [];
209
+ for (const key of keys) {
210
+ const desc = object.GetOwnProperty(key);
211
+ if (desc instanceof engine262.AbruptCompletion) {
212
+ return desc;
213
+ }
214
+ const descriptor = {
215
+ name: key.stringValue
216
+ ? key.stringValue()
217
+ : `Symbol(${key.Description.stringValue ? key.Description.stringValue() : ''})`,
218
+ };
219
+ if (desc.Value) {
220
+ desc.valuePreview = wrap(desc.Value).preview;
221
+ switch (engine262.Type(desc.Value)) {
222
+ case 'Object':
223
+ if ('Call' in desc.Value) {
224
+ descriptor.type = 'function';
225
+ } else {
226
+ descriptor.type = 'object';
227
+ if ('PromiseState' in desc.Value) {
228
+ descriptor.subtype = 'promise';
229
+ } else if ('MapData' in desc.Value) {
230
+ descriptor.subtype = 'map';
231
+ } else if ('SetData' in desc.Value) {
232
+ descriptor.subtype = 'set';
233
+ } else if ('ErrorData' in desc.Value) {
234
+ descriptor.subtype = 'error';
235
+ } else if ('TypedArrayName' in desc.Value) {
236
+ descriptor.subtype = 'typedarray';
237
+ } else if ('DataView' in desc.Value) {
238
+ descriptor.subtype = 'dataview';
239
+ } else if ('ProxyTarget' in desc.Value) {
240
+ descriptor.subtype = 'proxy';
241
+ } else if ('DateValue' in desc.Value) {
242
+ descriptor.subtype = 'date';
243
+ } else if ('GeneratorState' in desc.Value) {
244
+ descriptor.subtype = 'generator';
245
+ } else if (engine262.IsArray(desc.Value) === engine262.Value.true) {
246
+ descriptor.subtype = 'array';
247
+ }
248
+ }
249
+ break;
250
+ case 'Null':
251
+ descriptor.type = 'object';
252
+ descriptor.subtype = 'null';
253
+ descriptor.value = 'null';
254
+ break;
255
+ case 'Undefined':
256
+ descriptor.type = 'undefined';
257
+ descriptor.value = 'undefined';
258
+ break;
259
+ case 'String':
260
+ descriptor.type = 'string';
261
+ descriptor.value = desc.Value.stringValue();
262
+ break;
263
+ case 'Number': {
264
+ descriptor.type = 'number';
265
+ descriptor.value = desc.Value.numberValue().toString();
266
+ break;
267
+ }
268
+ case 'Boolean':
269
+ descriptor.type = 'boolean';
270
+ descriptor.value = desc.Value.booleanValue().toString();
271
+ break;
272
+ case 'BigInt':
273
+ descriptor.type = 'bigint';
274
+ descriptor.value = `${desc.Value.bigintValue().toString()}n`;
275
+ break;
276
+ case 'Symbol': {
277
+ descriptor.type = 'symbol';
278
+ const description = desc.Value.Description === engine262.Value.undefined
279
+ ? ''
280
+ : desc.Value.Description.stringValue();
281
+ descriptor.value = `Symbol(${description})`;
282
+ break;
283
+ }
284
+ default:
285
+ throw new RangeError();
286
+ }
287
+ } else {
288
+ desc.type = 'accessor';
289
+ }
290
+ properties.push(descriptor);
291
+ }
292
+
293
+ if ('PromiseState' in object) {
294
+ properties.push({
295
+ name: '[[PromiseState]]',
296
+ type: 'string',
297
+ value: object.PromiseState,
298
+ });
299
+ }
300
+
301
+ return properties;
302
+ }
303
+
304
+ createEvaluationResult(completion, options) {
305
+ if (completion instanceof engine262.AbruptCompletion) {
306
+ return {
307
+ exceptionDetails: {
308
+ text: 'uh oh',
309
+ lineNumber: 0,
310
+ columnNumber: 0,
311
+ exception: this.toRemoteObject(completion.Value, options),
312
+ },
313
+ };
314
+ } else {
315
+ return {
316
+ result: this.toRemoteObject(completion.Value, options),
317
+ };
318
+ }
319
+ }
320
+ }
321
+
322
+ function attachRealm(realm) {
323
+ contexts.push(new InspectorContext(realm));
324
+ }
325
+
326
+ function getContext(id) {
327
+ return contexts[id] || contexts[0];
328
+ }
329
+
330
+ module.exports = { attachRealm, getContext };
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ require('./server');
4
+ const { attachRealm } = require('./context');
5
+
6
+ module.exports = { attachRealm };