@swf2es/runtime 0.1.18 → 0.1.19

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.
@@ -2,6 +2,7 @@
2
2
  // calling or constructing Object, Namespace, QName or Function does.
3
3
 
4
4
  import type { AsObject, Value } from "../descriptors.js";
5
+ import { forgetStep } from "../enumeration.js";
5
6
  import type { ClassHook } from "../hooks.js";
6
7
  import { formatClassName, Namespace, prefixOf, publicQname } from "../names.js";
7
8
  import { NOT_FOUND, type Runtime } from "../runtime.js";
@@ -51,7 +52,11 @@ export const objectNatives: Natives = {
51
52
  o.$d.allHidden = false;
52
53
  }
53
54
  } else {
54
- o.$dontEnum ??= new Set();
55
+ if (o.$dontEnum === undefined) {
56
+ o.$dontEnum = new Set();
57
+ forgetStep(o);
58
+ }
59
+
55
60
  o.$dontEnum.add(name);
56
61
  }
57
62
  },
@@ -76,7 +76,7 @@ for (const [kind, , , elementsOf, store] of VECTORS) {
76
76
  a.length = length;
77
77
  } else if (length === 0) {
78
78
  // A new array: V8 empties one by a call into its runtime.
79
- this.$a = elementsOf(0);
79
+ rt.setElements(this, elementsOf(0));
80
80
  } else if (length < a.length) {
81
81
  a.length = length;
82
82
  } else if (length > a.length) {
@@ -39,13 +39,17 @@ import {
39
39
  continues,
40
40
  dictionaryAt,
41
41
  type Enumeration,
42
+ elementName,
42
43
  elementsAt,
43
44
  enumerated,
45
+ forgetStep,
44
46
  INT_ATOM_LIMIT,
45
47
  nextIndex,
46
48
  ownNames,
47
49
  pairIndex,
48
50
  pairOf,
51
+ sparseElement,
52
+ traitsAt,
49
53
  walkless,
50
54
  } from "./enumeration.js";
51
55
  import { AsError, describe, detailOf, errorMessage, stackOf, UnsupportedError } from "./errors.js";
@@ -2519,9 +2523,18 @@ export class Runtime {
2519
2523
  return this.array(values);
2520
2524
  }
2521
2525
 
2526
+ /**
2527
+ * Give `o`, which has elements, the storage `elements` in place of its
2528
+ * own, so that a for-in under way over it goes on over them.
2529
+ */
2530
+ setElements(o: AsObject, elements: Value[]): void {
2531
+ o.$a = elements;
2532
+ forgetStep(o);
2533
+ }
2534
+
2522
2535
  /** An Array holding `values`. */
2523
2536
  array(values: Value[]): AsObject {
2524
- const o = this.builtinTraits("Array").instance();
2537
+ const o = (this.arrayTraits ?? this.builtinTraits("Array")).instance();
2525
2538
  o.$a = values;
2526
2539
  return o;
2527
2540
  }
@@ -3349,7 +3362,7 @@ export class Runtime {
3349
3362
  }
3350
3363
 
3351
3364
  // As avmplus' ArrayObject and TypedVectorObject: the elements, then the other names.
3352
- const length = elementsAt(o, index);
3365
+ const length = elementsAt(o, index)?.length ?? 0;
3353
3366
  if (index > 0 && index <= length) {
3354
3367
  const element = index - 1;
3355
3368
  return element < INT_ATOM_LIMIT ? element : String(element);
@@ -3366,7 +3379,7 @@ export class Runtime {
3366
3379
  }
3367
3380
 
3368
3381
  nextValue(o: Value, index: number): Value {
3369
- const traits: Traits | undefined = o?.$traits;
3382
+ const traits: Traits | undefined = traitsAt(o, index);
3370
3383
  if (!continues(o, index)) {
3371
3384
  const properties = traits?.properties;
3372
3385
  if (properties) {
@@ -3386,7 +3399,8 @@ export class Runtime {
3386
3399
  }
3387
3400
  }
3388
3401
 
3389
- const length = elementsAt(o, index);
3402
+ const a = elementsAt(o, index);
3403
+ const length = a?.length ?? 0;
3390
3404
  if (index > 0 && index <= length) {
3391
3405
  const element = index - 1;
3392
3406
  if (traits?.getIndex) {
@@ -3395,8 +3409,8 @@ export class Runtime {
3395
3409
 
3396
3410
  if (traits === this.arrayTraits) {
3397
3411
  // A hole reads undefined too: only then is `in` asked.
3398
- const value = o.$a[element];
3399
- if (value !== undefined || element in o.$a) {
3412
+ const value = (a as Value[])[element];
3413
+ if (value !== undefined || element in (a as Value[])) {
3400
3414
  return value;
3401
3415
  }
3402
3416
  }
@@ -3410,12 +3424,22 @@ export class Runtime {
3410
3424
  }
3411
3425
 
3412
3426
  // Else a Dictionary's slot holds a dynamic property's name.
3413
- const name =
3414
- keys !== null
3415
- ? (keys.nameAt(index - length) as string)
3416
- : index <= length
3417
- ? String(index - 1)
3418
- : enumerated(o, index - length, index);
3427
+ let name: string;
3428
+ if (keys !== null) {
3429
+ name = keys.nameAt(index - length) as string;
3430
+ } else if (index <= length) {
3431
+ // A step by a sparse Array's indices reads its element here, off the path of every other.
3432
+ if (index < 0) {
3433
+ const value = sparseElement(o, index, traits === this.arrayTraits, NOT_FOUND);
3434
+ if (value !== NOT_FOUND) {
3435
+ return value;
3436
+ }
3437
+ }
3438
+
3439
+ name = elementName(index);
3440
+ } else {
3441
+ name = enumerated(o, index - length, index) as string;
3442
+ }
3419
3443
 
3420
3444
  // A dynamic property's value, as avmplus' nextValue reads its slot's:
3421
3445
  // no binding has its name, which setting it would have gone to.