@swf2es/runtime 0.1.14 → 0.1.16

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.
Files changed (48) hide show
  1. package/dist/avm2/cache-fill.d.ts +4 -1
  2. package/dist/avm2/cache-fill.d.ts.map +1 -1
  3. package/dist/avm2/cache-fill.js +5 -6
  4. package/dist/avm2/cache-fill.js.map +1 -1
  5. package/dist/avm2/descriptors.d.ts +6 -1
  6. package/dist/avm2/descriptors.d.ts.map +1 -1
  7. package/dist/avm2/descriptors.js.map +1 -1
  8. package/dist/avm2/errors.d.ts +14 -0
  9. package/dist/avm2/errors.d.ts.map +1 -1
  10. package/dist/avm2/errors.js +17 -0
  11. package/dist/avm2/errors.js.map +1 -1
  12. package/dist/avm2/index.d.ts +1 -0
  13. package/dist/avm2/index.d.ts.map +1 -1
  14. package/dist/avm2/index.js +1 -0
  15. package/dist/avm2/index.js.map +1 -1
  16. package/dist/avm2/names.d.ts +11 -0
  17. package/dist/avm2/names.d.ts.map +1 -1
  18. package/dist/avm2/names.js +12 -0
  19. package/dist/avm2/names.js.map +1 -1
  20. package/dist/avm2/natives/proxy.d.ts.map +1 -1
  21. package/dist/avm2/natives/proxy.js +9 -4
  22. package/dist/avm2/natives/proxy.js.map +1 -1
  23. package/dist/avm2/options.d.ts +5 -0
  24. package/dist/avm2/options.d.ts.map +1 -1
  25. package/dist/avm2/options.js.map +1 -1
  26. package/dist/avm2/property-cache.d.ts +17 -13
  27. package/dist/avm2/property-cache.d.ts.map +1 -1
  28. package/dist/avm2/property-cache.js +50 -10
  29. package/dist/avm2/property-cache.js.map +1 -1
  30. package/dist/avm2/runtime.d.ts +62 -0
  31. package/dist/avm2/runtime.d.ts.map +1 -1
  32. package/dist/avm2/runtime.js +245 -25
  33. package/dist/avm2/runtime.js.map +1 -1
  34. package/dist/avm2/traits.d.ts +7 -0
  35. package/dist/avm2/traits.d.ts.map +1 -1
  36. package/dist/avm2/traits.js +6 -0
  37. package/dist/avm2/traits.js.map +1 -1
  38. package/package.json +2 -2
  39. package/src/avm2/cache-fill.ts +5 -7
  40. package/src/avm2/descriptors.ts +6 -2
  41. package/src/avm2/errors.ts +18 -0
  42. package/src/avm2/index.ts +1 -0
  43. package/src/avm2/names.ts +13 -0
  44. package/src/avm2/natives/proxy.ts +20 -4
  45. package/src/avm2/options.ts +5 -0
  46. package/src/avm2/property-cache.ts +57 -11
  47. package/src/avm2/runtime.ts +280 -26
  48. package/src/avm2/traits.ts +7 -1
@@ -21,18 +21,18 @@ import { NAMED } from "./dictionary-keys.js";
21
21
  import { compileUnit, Domain, definitionNames, findScript } from "./domain.js";
22
22
  import { isViewRangeError, SharedMemoryView } from "./domain-memory.js";
23
23
  import { continues, dictionaryAt, elementsAt, enumerated, INT_ATOM_LIMIT, nextIndex, ownNames, pairIndex, pairOf, walkless, } from "./enumeration.js";
24
- import { AsError, describe, errorMessage, stackOf } from "./errors.js";
24
+ import { AsError, describe, detailOf, errorMessage, stackOf, UnsupportedError } from "./errors.js";
25
25
  import { FloatValue, floatValue } from "./float.js";
26
26
  import { hookedBinding } from "./hooks.js";
27
27
  import { installMethod, nativeFactory, noBodyFactory, unverifiedFactory, verifyErrorFactory, } from "./method-factories.js";
28
28
  import { Modules } from "./modules.js";
29
- import { arrayIndex, CONSTANT_Multiname, CONSTANT_MultinameA, CONSTANT_MultinameL, CONSTANT_MultinameLA, CONSTANT_Qname, CONSTANT_RTQname, CONSTANT_RTQnameA, CONSTANT_RTQnameL, CONSTANT_RTQnameLA, Multiname, Namespace, NS_Private, NS_Public, namespace, prefixedNamespace, prefixOf, publicNs, publicQname, qname, TypeName, } from "./names.js";
29
+ import { arrayIndex, CONSTANT_Multiname, CONSTANT_MultinameA, CONSTANT_MultinameL, CONSTANT_MultinameLA, CONSTANT_Qname, CONSTANT_RTQname, CONSTANT_RTQnameA, CONSTANT_RTQnameL, CONSTANT_RTQnameLA, MADE_Number, MADE_Value, Multiname, Namespace, NS_Private, NS_Public, namespace, prefixedNamespace, prefixOf, publicNs, publicQname, qname, TypeName, } from "./names.js";
30
30
  import { FloatVector, setFloatElement } from "./natives/float-vector.js";
31
31
  import { storeDouble, storeInt, storeObject, } from "./natives/vector-elements.js";
32
32
  import { escapeAttributeValue, escapeElementValue } from "./natives/xml/escape.js";
33
33
  import { numberToString, stringToNumber } from "./number-strings.js";
34
34
  import { defaultPrint, memoryFiles, } from "./options.js";
35
- import { cached, epoch, IC_Call, IC_Const, IC_Dynamic, IC_Get, IC_GetSet, IC_Method, IC_Set, IC_Slot, invalidate, NO_CACHE, REPLACEMENTS, UNFILLED, } from "./property-cache.js";
35
+ import { cached, epoch, IC_Call, IC_Const, IC_Dynamic, IC_Get, IC_GetSet, IC_Method, IC_Set, IC_Slot, invalidate, NO_CACHE, ScopeFinds, UNFILLED, } from "./property-cache.js";
36
36
  import { BIND_Const, BIND_Get, BIND_GetSet, BIND_Method, BIND_Set, BIND_Var, boundKey, ClassRef, methodKey, slotKey, Traits, untypedSetKey, VectorRef, } from "./traits.js";
37
37
  export { NOT_FOUND } from "./descriptors.js";
38
38
  /**
@@ -54,6 +54,16 @@ class ScopePack {
54
54
  this.w = w;
55
55
  }
56
56
  }
57
+ /** Whether a chain or a pack, `scopes` with bits `w`, has a with scope, in a pack in it too. */
58
+ function hasWith(scopes, w) {
59
+ for (let i = 0; i < scopes.length; i++) {
60
+ const o = scopes[i];
61
+ if (o instanceof ScopePack ? hasWith(o.scopes, o.w) : (w >> i) & 1) {
62
+ return true;
63
+ }
64
+ }
65
+ return false;
66
+ }
57
67
  /** The value of `o`'s dynamic property `name`, or NOT_FOUND. */
58
68
  function dynamicValue(o, name) {
59
69
  const d = o.$d;
@@ -67,6 +77,7 @@ export class Runtime {
67
77
  classHooks;
68
78
  print;
69
79
  debugger;
80
+ onUnsupported;
70
81
  compileAbc;
71
82
  files;
72
83
  /** See RuntimeOptions.workers and worker. */
@@ -147,7 +158,7 @@ export class Runtime {
147
158
  /** Special traits: an activation's or a catch scope's, by descriptor. */
148
159
  scopeTraits = new WeakMap();
149
160
  specialized = new Map();
150
- empty = Object.assign([], { w: 0 });
161
+ empty = Object.assign([], { w: 0, found: undefined });
151
162
  /**
152
163
  * `natives` are the natives by name, or a provider that makes them for
153
164
  * this runtime, so that a natives module can close over its runtime (as a
@@ -158,6 +169,7 @@ export class Runtime {
158
169
  this.classHooks = classHooks;
159
170
  this.print = options.print ?? defaultPrint;
160
171
  this.debugger = options.debugger ?? false;
172
+ this.onUnsupported = options.onUnsupported;
161
173
  this.compileAbc = options.compileAbc ?? null;
162
174
  this.files = options.files ?? memoryFiles();
163
175
  this.workerHost = options.workers ?? null;
@@ -289,6 +301,7 @@ export class Runtime {
289
301
  // Its string only once a lookup needs it: a Dictionary does not.
290
302
  const keyed = Multiname.keyed(kind, namespaces, versions, part, mn.attribute, this.keyName);
291
303
  keyed.domain = mn.domain;
304
+ keyed.made = MADE_Value;
292
305
  return keyed;
293
306
  }
294
307
  else {
@@ -297,6 +310,37 @@ export class Runtime {
297
310
  }
298
311
  const named = new Multiname(kind, namespaces, versions, name, mn.attribute);
299
312
  named.domain = mn.domain;
313
+ // A number here is one no element access made: a Proxy tells it by its string.
314
+ if (mn.runtimeName && typeof last !== "number") {
315
+ named.made = MADE_Value;
316
+ }
317
+ return named;
318
+ }
319
+ /**
320
+ * The name runtimeName makes of `mn`, a MultinameL, and a string the
321
+ * code itself holds, `obj["name"]`: a module makes it once as it loads
322
+ * and keeps it as it keeps `mn`, so it has a cache as a module's own
323
+ * names have, however many such names the module has and however long
324
+ * the string is.
325
+ */
326
+ literalName(mn, name) {
327
+ const named = new Multiname(mn.kind, mn.namespaces, mn.versions, name, mn.attribute);
328
+ named.domain = mn.domain;
329
+ named.made = MADE_Value;
330
+ named.cache = UNFILLED;
331
+ return named;
332
+ }
333
+ /**
334
+ * The name number `i` makes of `mn` in an element's read or write, which
335
+ * avmplus' JIT hands an object as a number (getpropertylate_i and _d), a
336
+ * Proxy as its string: where the name has no public namespace, it is a
337
+ * name as any other.
338
+ */
339
+ indexName(mn, i) {
340
+ const named = this.runtimeName(mn, i);
341
+ if (mn.kind === CONSTANT_MultinameL && mn.elementName) {
342
+ named.made = MADE_Number;
343
+ }
300
344
  return named;
301
345
  }
302
346
  stringNames = new WeakMap();
@@ -318,6 +362,7 @@ export class Runtime {
318
362
  }
319
363
  const named = new Multiname(base.kind, base.namespaces, base.versions, name, base.attribute);
320
364
  named.domain = base.domain;
365
+ named.made = MADE_Value;
321
366
  if (!cache) {
322
367
  cache = { names: new Map(), misses: 0 };
323
368
  this.stringNames.set(base, cache);
@@ -417,6 +462,7 @@ export class Runtime {
417
462
  const traits = new Traits("global", this.objectTraits);
418
463
  traits.dynamic = true;
419
464
  traits.isGlobal = true;
465
+ traits.abc = script.abc;
420
466
  traits.describe(script.desc.traits);
421
467
  const g = traits.instance();
422
468
  // As the script's initializer, its methods run in an empty scope chain,
@@ -490,6 +536,7 @@ export class Runtime {
490
536
  scope(outer, locals, withs) {
491
537
  const chain = outer.concat(locals);
492
538
  chain.w = outer.w | (withs << outer.length);
539
+ chain.found = undefined;
493
540
  return chain;
494
541
  }
495
542
  /**
@@ -504,6 +551,7 @@ export class Runtime {
504
551
  const packed = chain.slice(0, at);
505
552
  packed.push(new ScopePack(chain.slice(at), chain.w >>> at));
506
553
  packed.w = (chain.w & ((1 << at) - 1)) | (1 << at);
554
+ packed.found = undefined;
507
555
  return packed;
508
556
  }
509
557
  /**
@@ -532,6 +580,40 @@ export class Runtime {
532
580
  return locals[i];
533
581
  }
534
582
  }
583
+ const found = this.outerScopeOf(outer, mn);
584
+ if (found !== null) {
585
+ return found;
586
+ }
587
+ return this.global(mn, outer.length ? outer[0] : locals[0], strict);
588
+ }
589
+ /**
590
+ * The innermost object of a captured chain that has `mn`, or null: kept
591
+ * on a chain without a with scope (ScopeFinds), as a function whose
592
+ * chain the compiler could not type, such as one made where chains of
593
+ * different lengths meet, looks its names up each time it runs.
594
+ */
595
+ outerScopeOf(outer, mn) {
596
+ let finds = outer.found;
597
+ if (finds === undefined) {
598
+ finds = hasWith(outer, outer.w) ? null : new ScopeFinds();
599
+ outer.found = finds;
600
+ }
601
+ // A name made at run time is a new one each time: keeping it would only grow the map.
602
+ if (finds === null || mn.cache === NO_CACHE) {
603
+ return this.searchOuter(outer, mn);
604
+ }
605
+ if (finds.epoch !== epoch()) {
606
+ finds.clear();
607
+ finds.epoch = epoch();
608
+ }
609
+ let o = finds.get(mn);
610
+ if (o === undefined) {
611
+ o = this.searchOuter(outer, mn);
612
+ finds.set(mn, o);
613
+ }
614
+ return o;
615
+ }
616
+ searchOuter(outer, mn) {
535
617
  for (let i = outer.length - 1; i >= 0; i--) {
536
618
  const o = outer[i];
537
619
  if (o instanceof ScopePack) {
@@ -544,7 +626,7 @@ export class Runtime {
544
626
  return o;
545
627
  }
546
628
  }
547
- return this.global(mn, outer.length ? outer[0] : locals[0], strict);
629
+ return null;
548
630
  }
549
631
  findPropertyStrict(mn, outer, locals, withs) {
550
632
  return this.findProperty(mn, outer, locals, withs, true);
@@ -669,15 +751,22 @@ export class Runtime {
669
751
  traitsOf(v) {
670
752
  switch (typeof v) {
671
753
  case "object":
672
- case "function":
754
+ case "function": {
673
755
  if (v === null) {
674
756
  throw this.error("TypeError", 1009);
675
757
  }
758
+ // An object's own first: instanceof walks the whole prototype
759
+ // chain of an object, and a class's is as deep as its bases.
760
+ const traits = v.$traits;
761
+ if (traits !== undefined) {
762
+ return traits;
763
+ }
676
764
  return v instanceof FloatValue
677
765
  ? this.builtinTraits("float")
678
766
  : v instanceof Namespace
679
767
  ? this.builtinTraits("Namespace")
680
- : v.$traits;
768
+ : traits;
769
+ }
681
770
  // As avmplus' toVTable: every number is a Number at run time, int or
682
771
  // not; int's and uint's traits only bind early, from static types.
683
772
  case "number":
@@ -698,12 +787,17 @@ export class Runtime {
698
787
  receiverTraits(v) {
699
788
  switch (typeof v) {
700
789
  case "object":
701
- case "function":
702
- return v instanceof FloatValue
703
- ? this.builtinTraits("float")
704
- : v === null
705
- ? undefined
706
- : v.$traits;
790
+ case "function": {
791
+ if (v === null) {
792
+ return undefined;
793
+ }
794
+ // A float and a Namespace have none of their own (see traitsOf).
795
+ const traits = v.$traits;
796
+ if (traits !== undefined) {
797
+ return traits;
798
+ }
799
+ return v instanceof FloatValue ? this.builtinTraits("float") : undefined;
800
+ }
707
801
  case "string":
708
802
  return this.stringTraits;
709
803
  case "number":
@@ -877,7 +971,7 @@ export class Runtime {
877
971
  }
878
972
  }
879
973
  }
880
- return this.getProperty(o, this.runtimeName(mn, i));
974
+ return this.getProperty(o, this.indexName(mn, i));
881
975
  }
882
976
  /** obj[i] = v for a number i, as avmplus' setUintProperty. */
883
977
  setIndexed(o, mn, i, v) {
@@ -889,12 +983,93 @@ export class Runtime {
889
983
  traits.setIndex(o, i, v, this);
890
984
  return;
891
985
  }
892
- if (o.$a !== undefined && o.$a !== SEALED_ELEMENTS && i !== 0xffffffff) {
893
- o.$a[i] = v;
894
- return;
986
+ const a = o.$a;
987
+ if (a !== undefined) {
988
+ if (a !== SEALED_ELEMENTS && i !== 0xffffffff) {
989
+ a[i] = v;
990
+ return;
991
+ }
992
+ }
993
+ else if (traits?.dynamic && traits.properties === null && !traits.refusesNames) {
994
+ // As ScriptObject::setUintProperty: an object with no elements of its own keeps the
995
+ // number among its dynamic properties, with no binding asked for.
996
+ const d = o.$d;
997
+ if (d) {
998
+ d.set(`${i}`, v);
999
+ return;
1000
+ }
895
1001
  }
896
1002
  }
897
- this.setProperty(o, this.runtimeName(mn, i), v);
1003
+ this.setProperty(o, this.indexName(mn, i), v);
1004
+ }
1005
+ /**
1006
+ * obj[k] for a key whose type the compiler does not know, by a name with
1007
+ * no namespace from the stack, as avmplus' getprop_index and
1008
+ * getpropertyHelper: a number is an index (getIndexed), an object a
1009
+ * Dictionary has as a key is read by itself, and anything else, a QName
1010
+ * and a Dictionary's absent key among them, is looked up by the name it
1011
+ * makes.
1012
+ */
1013
+ getKeyed(o, mn, k) {
1014
+ let r;
1015
+ if (typeof k === "number") {
1016
+ r = this.getIndexed(o, mn, k);
1017
+ return r;
1018
+ }
1019
+ if (typeof k === "object" && k !== null) {
1020
+ const keys = o?.$keys;
1021
+ if (keys !== undefined) {
1022
+ if (!mn.elementName) {
1023
+ r = this.getProperty(o, this.runtimeName(mn, this.unkeyed(k)));
1024
+ return r;
1025
+ }
1026
+ // What is there was put there by a name with the object as its key, which a QName's is not.
1027
+ const v = keys.get(k);
1028
+ if (v !== undefined) {
1029
+ return v;
1030
+ }
1031
+ }
1032
+ }
1033
+ r = this.getProperty(o, this.runtimeName(mn, k));
1034
+ return r;
1035
+ }
1036
+ /**
1037
+ * An object given as the key of a Dictionary by a name with no public
1038
+ * namespace, as the name is made of it: avmplus' JIT asks a Dictionary
1039
+ * for an object only through getprop_index and setprop_index, which such
1040
+ * a name does not reach, so the object is its string, as on any other
1041
+ * receiver (initMultinameLate); a QName names what it names. Its
1042
+ * interpreter asks the Dictionary by any name, as a name made without
1043
+ * this does: the compiler leaves script and class initializers to that.
1044
+ */
1045
+ unkeyed(k) {
1046
+ return k.$traits !== undefined && k.$local === undefined ? this.toString(k) : k;
1047
+ }
1048
+ /** obj[k] = v for a key whose type the compiler does not know, as avmplus' setprop_index and setpropertyHelper. */
1049
+ setKeyed(o, mn, k, v) {
1050
+ if (typeof k === "number") {
1051
+ this.setIndexed(o, mn, k, v);
1052
+ return;
1053
+ }
1054
+ if (typeof k === "object" && k !== null) {
1055
+ const keys = o?.$keys;
1056
+ if (keys !== undefined) {
1057
+ if (!mn.elementName) {
1058
+ this.setProperty(o, this.runtimeName(mn, this.unkeyed(k)), v);
1059
+ return;
1060
+ }
1061
+ if (keys.replace(k, v)) {
1062
+ return;
1063
+ }
1064
+ // A new key: an object of traits, which a float and a Namespace are not, and no QName,
1065
+ // which names what it names. Those are added, or not, by the name they make.
1066
+ if (k.$traits !== undefined && k.$local === undefined) {
1067
+ keys.add(k, v);
1068
+ return;
1069
+ }
1070
+ }
1071
+ }
1072
+ this.setProperty(o, this.runtimeName(mn, k), v);
898
1073
  }
899
1074
  /**
900
1075
  * Element i of Vector o set to x, already converted, as
@@ -1093,9 +1268,7 @@ export class Runtime {
1093
1268
  /** fillCache (cache-fill.ts), for a name that caches on traits a cache knows `o` by. */
1094
1269
  fill(o, traits, b, mn) {
1095
1270
  const head = mn.cache;
1096
- if (head === NO_CACHE ||
1097
- (head.replaced === REPLACEMENTS && head.epoch === epoch()) ||
1098
- this.receiverTraits(o) !== traits) {
1271
+ if (head === NO_CACHE || this.receiverTraits(o) !== traits) {
1099
1272
  return;
1100
1273
  }
1101
1274
  fillCache(head, o, traits, b, mn);
@@ -1124,6 +1297,8 @@ export class Runtime {
1124
1297
  f.$length = method.$length ?? method.length;
1125
1298
  f.$id = method.$id ?? 0;
1126
1299
  f.$closure = true;
1300
+ // Whose method it is, for moduleOf.
1301
+ f.$of = traits;
1127
1302
  if (typeof o === "object") {
1128
1303
  byMethod.set(method, f);
1129
1304
  }
@@ -1388,8 +1563,7 @@ export class Runtime {
1388
1563
  // A namespace is the runtime's own object: its prototype is its class's.
1389
1564
  if (typeof o === "object" &&
1390
1565
  o !== null &&
1391
- !(o instanceof Namespace) &&
1392
- !(o instanceof FloatValue)) {
1566
+ (o.$traits !== undefined || !(o instanceof Namespace || o instanceof FloatValue))) {
1393
1567
  return o.$p;
1394
1568
  }
1395
1569
  return this.traitsOf(o).proto.$p;
@@ -1809,6 +1983,19 @@ export class Runtime {
1809
1983
  this.functionObjects.set(method, f);
1810
1984
  return f;
1811
1985
  }
1986
+ /**
1987
+ * The module a function's code is from, as avmplus has a method's code
1988
+ * context: a function's by the global object its scope begins with, a
1989
+ * bound method's by its receiver's class; null for a native, a class's
1990
+ * own method, or anything but a function.
1991
+ */
1992
+ moduleOf(f) {
1993
+ const o = f;
1994
+ if (o?.$of) {
1995
+ return o.$of.abc;
1996
+ }
1997
+ return o?.$global ? this.traitsOf(o.$global).abc : null;
1998
+ }
1812
1999
  /** A Function object calling `f`, with `global` as its receiver when it has none. */
1813
2000
  newFunctionObject(f, global) {
1814
2001
  const o = this.functionTraits.instance();
@@ -2543,12 +2730,21 @@ export class Runtime {
2543
2730
  catch {
2544
2731
  return new AsError(`${name}: ${message}`);
2545
2732
  }
2546
- return this.constructClass(cls, [message, id]);
2733
+ const made = this.constructClass(cls, [message, id]);
2734
+ // What the number stands for, kept beside the message for a host's report (detailOf).
2735
+ if (!this.debugger) {
2736
+ Object.defineProperty(made, "$detail", { value: errorMessage(true, id, args) });
2737
+ }
2738
+ return made;
2547
2739
  }
2548
2740
  /** See stackOf in errors.ts. */
2549
2741
  stackOf(error) {
2550
2742
  return stackOf(error);
2551
2743
  }
2744
+ /** See detailOf in errors.ts. */
2745
+ detailOf(error) {
2746
+ return detailOf(error);
2747
+ }
2552
2748
  /** See errorMessage in errors.ts. */
2553
2749
  errorMessage(id, args = []) {
2554
2750
  return errorMessage(this.debugger, id, args);
@@ -2573,11 +2769,35 @@ export class Runtime {
2573
2769
  if (isViewRangeError(e)) {
2574
2770
  return this.error("RangeError", 1506);
2575
2771
  }
2772
+ if (e instanceof UnsupportedError) {
2773
+ return this.unsupportedCaught(e);
2774
+ }
2576
2775
  if (e instanceof Error && !(e instanceof AsError)) {
2577
2776
  throw e;
2578
2777
  }
2579
2778
  return e;
2580
2779
  }
2780
+ /** What a catch was told of already (unsupportedCaught). */
2781
+ unsupportedTold = new Set();
2782
+ /**
2783
+ * What is not supported as the AS3 error a catch gets: an
2784
+ * IllegalOperationError with its message, or an Error where the player's
2785
+ * classes are not loaded; said once to the host, as the code may say nothing.
2786
+ */
2787
+ unsupportedCaught(e) {
2788
+ if (!this.unsupportedTold.has(e.message)) {
2789
+ this.unsupportedTold.add(e.message);
2790
+ this.onUnsupported?.(e.message);
2791
+ }
2792
+ let cls;
2793
+ try {
2794
+ cls = this.resolve(this.cls(namespace(NS_Public, "flash.errors"), "IllegalOperationError"));
2795
+ }
2796
+ catch {
2797
+ cls = this.builtinClass("Error");
2798
+ }
2799
+ return this.constructClass(cls, [e.message, 0]);
2800
+ }
2581
2801
  catches(e, type) {
2582
2802
  return this.isInstanceOf(e, this.traitsOfType(type));
2583
2803
  }
@@ -2585,7 +2805,7 @@ export class Runtime {
2585
2805
  return new Error("swf2es: a dispatcher reached no block");
2586
2806
  }
2587
2807
  unsupported(what) {
2588
- return new Error(`swf2es: ${what} is not supported yet`);
2808
+ return new UnsupportedError(`swf2es: ${what} is not supported yet`);
2589
2809
  }
2590
2810
  // Class aliases and the classes AMF makes (amf-classes.ts).
2591
2811
  registerClassAlias(name, cls) {