@swf2es/runtime 0.1.15 → 0.1.17
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/dist/avm2/amf.d.ts +1 -1
- package/dist/avm2/amf.d.ts.map +1 -1
- package/dist/avm2/amf.js +4 -3
- package/dist/avm2/amf.js.map +1 -1
- package/dist/avm2/as3-types.d.ts +25 -0
- package/dist/avm2/as3-types.d.ts.map +1 -0
- package/dist/avm2/as3-types.js +9 -0
- package/dist/avm2/as3-types.js.map +1 -0
- package/dist/avm2/builtin-types.generated.d.ts +553 -0
- package/dist/avm2/builtin-types.generated.d.ts.map +1 -0
- package/dist/avm2/builtin-types.generated.js +11 -0
- package/dist/avm2/builtin-types.generated.js.map +1 -0
- package/dist/avm2/cache-fill.d.ts +4 -1
- package/dist/avm2/cache-fill.d.ts.map +1 -1
- package/dist/avm2/cache-fill.js +5 -6
- package/dist/avm2/cache-fill.js.map +1 -1
- package/dist/avm2/classes.d.ts.map +1 -1
- package/dist/avm2/classes.js +10 -3
- package/dist/avm2/classes.js.map +1 -1
- package/dist/avm2/descriptors.d.ts +6 -1
- package/dist/avm2/descriptors.d.ts.map +1 -1
- package/dist/avm2/descriptors.js.map +1 -1
- package/dist/avm2/errors.d.ts +14 -0
- package/dist/avm2/errors.d.ts.map +1 -1
- package/dist/avm2/errors.js +20 -1
- package/dist/avm2/errors.js.map +1 -1
- package/dist/avm2/index.d.ts +4 -0
- package/dist/avm2/index.d.ts.map +1 -1
- package/dist/avm2/index.js +3 -0
- package/dist/avm2/index.js.map +1 -1
- package/dist/avm2/names.d.ts +11 -0
- package/dist/avm2/names.d.ts.map +1 -1
- package/dist/avm2/names.js +12 -0
- package/dist/avm2/names.js.map +1 -1
- package/dist/avm2/natives/array.js +1 -1
- package/dist/avm2/natives/array.js.map +1 -1
- package/dist/avm2/natives/bytearray.d.ts.map +1 -1
- package/dist/avm2/natives/bytearray.js +6 -11
- package/dist/avm2/natives/bytearray.js.map +1 -1
- package/dist/avm2/natives/describe.js +6 -1
- package/dist/avm2/natives/describe.js.map +1 -1
- package/dist/avm2/natives/object.d.ts.map +1 -1
- package/dist/avm2/natives/object.js +5 -2
- package/dist/avm2/natives/object.js.map +1 -1
- package/dist/avm2/natives/proxy.d.ts.map +1 -1
- package/dist/avm2/natives/proxy.js +9 -4
- package/dist/avm2/natives/proxy.js.map +1 -1
- package/dist/avm2/natives/vector.js +1 -1
- package/dist/avm2/natives/vector.js.map +1 -1
- package/dist/avm2/options.d.ts +5 -0
- package/dist/avm2/options.d.ts.map +1 -1
- package/dist/avm2/options.js.map +1 -1
- package/dist/avm2/property-cache.d.ts +17 -13
- package/dist/avm2/property-cache.d.ts.map +1 -1
- package/dist/avm2/property-cache.js +50 -10
- package/dist/avm2/property-cache.js.map +1 -1
- package/dist/avm2/runtime.d.ts +101 -1
- package/dist/avm2/runtime.d.ts.map +1 -1
- package/dist/avm2/runtime.js +351 -45
- package/dist/avm2/runtime.js.map +1 -1
- package/dist/avm2/traits.d.ts +13 -0
- package/dist/avm2/traits.d.ts.map +1 -1
- package/dist/avm2/traits.js +23 -0
- package/dist/avm2/traits.js.map +1 -1
- package/package.json +2 -2
- package/src/avm2/amf.ts +4 -3
- package/src/avm2/as3-types.ts +41 -0
- package/src/avm2/builtin-types.generated.ts +619 -0
- package/src/avm2/cache-fill.ts +5 -7
- package/src/avm2/classes.ts +10 -3
- package/src/avm2/descriptors.ts +6 -2
- package/src/avm2/errors.ts +21 -1
- package/src/avm2/index.ts +6 -0
- package/src/avm2/names.ts +13 -0
- package/src/avm2/natives/array.ts +1 -1
- package/src/avm2/natives/bytearray.ts +6 -14
- package/src/avm2/natives/describe.ts +8 -1
- package/src/avm2/natives/object.ts +5 -2
- package/src/avm2/natives/proxy.ts +20 -4
- package/src/avm2/natives/vector.ts +1 -1
- package/src/avm2/options.ts +5 -0
- package/src/avm2/property-cache.ts +57 -11
- package/src/avm2/runtime.ts +407 -53
- package/src/avm2/traits.ts +27 -1
package/dist/avm2/runtime.js
CHANGED
|
@@ -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,
|
|
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,7 +54,27 @@ 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. */
|
|
68
|
+
/** Whether k is an int atom avmplus can take as a uint: an integer of 0 to 2^32-1, -0 not, as it is a double's. */
|
|
69
|
+
function uintAtom(k) {
|
|
70
|
+
return typeof k === "number" && k >>> 0 === k && (k !== 0 || 1 / k > 0);
|
|
71
|
+
}
|
|
72
|
+
/** Whether v is an object's atom to avmplus: not null, nor a Namespace or float, whose atoms are their own. */
|
|
73
|
+
function isScriptObject(v) {
|
|
74
|
+
return (typeof v === "object" && v !== null && !(v instanceof Namespace) && !(v instanceof FloatValue));
|
|
75
|
+
}
|
|
76
|
+
/** The name avmplus' getUintProperty looks a number up by: public, at every version. */
|
|
77
|
+
const ELEMENT_NAME = new Multiname(CONSTANT_MultinameL, [publicNs], [255], null, false);
|
|
58
78
|
function dynamicValue(o, name) {
|
|
59
79
|
const d = o.$d;
|
|
60
80
|
if (!d) {
|
|
@@ -67,6 +87,7 @@ export class Runtime {
|
|
|
67
87
|
classHooks;
|
|
68
88
|
print;
|
|
69
89
|
debugger;
|
|
90
|
+
onUnsupported;
|
|
70
91
|
compileAbc;
|
|
71
92
|
files;
|
|
72
93
|
/** See RuntimeOptions.workers and worker. */
|
|
@@ -127,6 +148,13 @@ export class Runtime {
|
|
|
127
148
|
/** The builtin classes' traits, made before their classes so the bootstrap can refer to them. */
|
|
128
149
|
objectTraits;
|
|
129
150
|
classTraits;
|
|
151
|
+
/**
|
|
152
|
+
* What the super operations of a script's methods and of a class's
|
|
153
|
+
* static ones look in, as avmplus' script traits extend Object and a
|
|
154
|
+
* class object's traits Class: their `super` is that class's instance.
|
|
155
|
+
*/
|
|
156
|
+
scriptSuper;
|
|
157
|
+
staticSuper;
|
|
130
158
|
functionTraits;
|
|
131
159
|
/**
|
|
132
160
|
* Method closures, by receiver and method, so that o.f === o.f; by the
|
|
@@ -147,7 +175,7 @@ export class Runtime {
|
|
|
147
175
|
/** Special traits: an activation's or a catch scope's, by descriptor. */
|
|
148
176
|
scopeTraits = new WeakMap();
|
|
149
177
|
specialized = new Map();
|
|
150
|
-
empty = Object.assign([], { w: 0 });
|
|
178
|
+
empty = Object.assign([], { w: 0, found: undefined });
|
|
151
179
|
/**
|
|
152
180
|
* `natives` are the natives by name, or a provider that makes them for
|
|
153
181
|
* this runtime, so that a natives module can close over its runtime (as a
|
|
@@ -158,6 +186,7 @@ export class Runtime {
|
|
|
158
186
|
this.classHooks = classHooks;
|
|
159
187
|
this.print = options.print ?? defaultPrint;
|
|
160
188
|
this.debugger = options.debugger ?? false;
|
|
189
|
+
this.onUnsupported = options.onUnsupported;
|
|
161
190
|
this.compileAbc = options.compileAbc ?? null;
|
|
162
191
|
this.files = options.files ?? memoryFiles();
|
|
163
192
|
this.workerHost = options.workers ?? null;
|
|
@@ -177,6 +206,8 @@ export class Runtime {
|
|
|
177
206
|
this.objectTraits.dynamic = true;
|
|
178
207
|
this.objectTraits.testsValues = true;
|
|
179
208
|
this.classTraits = new Traits("Class", this.objectTraits);
|
|
209
|
+
this.scriptSuper = { $it: this.objectTraits };
|
|
210
|
+
this.staticSuper = { $it: this.classTraits };
|
|
180
211
|
this.functionTraits = new Traits("Function", this.objectTraits);
|
|
181
212
|
this.functionTraits.dynamic = true;
|
|
182
213
|
this.natives = typeof natives === "function" ? natives(this) : natives;
|
|
@@ -289,6 +320,7 @@ export class Runtime {
|
|
|
289
320
|
// Its string only once a lookup needs it: a Dictionary does not.
|
|
290
321
|
const keyed = Multiname.keyed(kind, namespaces, versions, part, mn.attribute, this.keyName);
|
|
291
322
|
keyed.domain = mn.domain;
|
|
323
|
+
keyed.made = MADE_Value;
|
|
292
324
|
return keyed;
|
|
293
325
|
}
|
|
294
326
|
else {
|
|
@@ -297,6 +329,37 @@ export class Runtime {
|
|
|
297
329
|
}
|
|
298
330
|
const named = new Multiname(kind, namespaces, versions, name, mn.attribute);
|
|
299
331
|
named.domain = mn.domain;
|
|
332
|
+
// A number here is one no element access made: a Proxy tells it by its string.
|
|
333
|
+
if (mn.runtimeName && typeof last !== "number") {
|
|
334
|
+
named.made = MADE_Value;
|
|
335
|
+
}
|
|
336
|
+
return named;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* The name runtimeName makes of `mn`, a MultinameL, and a string the
|
|
340
|
+
* code itself holds, `obj["name"]`: a module makes it once as it loads
|
|
341
|
+
* and keeps it as it keeps `mn`, so it has a cache as a module's own
|
|
342
|
+
* names have, however many such names the module has and however long
|
|
343
|
+
* the string is.
|
|
344
|
+
*/
|
|
345
|
+
literalName(mn, name) {
|
|
346
|
+
const named = new Multiname(mn.kind, mn.namespaces, mn.versions, name, mn.attribute);
|
|
347
|
+
named.domain = mn.domain;
|
|
348
|
+
named.made = MADE_Value;
|
|
349
|
+
named.cache = UNFILLED;
|
|
350
|
+
return named;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* The name number `i` makes of `mn` in an element's read or write, which
|
|
354
|
+
* avmplus' JIT hands an object as a number (getpropertylate_i and _d), a
|
|
355
|
+
* Proxy as its string: where the name has no public namespace, it is a
|
|
356
|
+
* name as any other.
|
|
357
|
+
*/
|
|
358
|
+
indexName(mn, i) {
|
|
359
|
+
const named = this.runtimeName(mn, i);
|
|
360
|
+
if (mn.kind === CONSTANT_MultinameL && mn.elementName) {
|
|
361
|
+
named.made = MADE_Number;
|
|
362
|
+
}
|
|
300
363
|
return named;
|
|
301
364
|
}
|
|
302
365
|
stringNames = new WeakMap();
|
|
@@ -318,6 +381,7 @@ export class Runtime {
|
|
|
318
381
|
}
|
|
319
382
|
const named = new Multiname(base.kind, base.namespaces, base.versions, name, base.attribute);
|
|
320
383
|
named.domain = base.domain;
|
|
384
|
+
named.made = MADE_Value;
|
|
321
385
|
if (!cache) {
|
|
322
386
|
cache = { names: new Map(), misses: 0 };
|
|
323
387
|
this.stringNames.set(base, cache);
|
|
@@ -417,6 +481,7 @@ export class Runtime {
|
|
|
417
481
|
const traits = new Traits("global", this.objectTraits);
|
|
418
482
|
traits.dynamic = true;
|
|
419
483
|
traits.isGlobal = true;
|
|
484
|
+
traits.abc = script.abc;
|
|
420
485
|
traits.describe(script.desc.traits);
|
|
421
486
|
const g = traits.instance();
|
|
422
487
|
// As the script's initializer, its methods run in an empty scope chain,
|
|
@@ -424,7 +489,9 @@ export class Runtime {
|
|
|
424
489
|
// indexes the scopes their closures capture: the global object is
|
|
425
490
|
// only what they push.
|
|
426
491
|
for (const [d, factory, id, , params] of script.desc.traits.methods) {
|
|
427
|
-
|
|
492
|
+
const method = withId(factory(this.empty, this.scriptSuper), id);
|
|
493
|
+
this.keepStatic(factory, method);
|
|
494
|
+
installMethod(this, traits.methodHome(3), d, method, factory, params);
|
|
428
495
|
}
|
|
429
496
|
// Caches keep the methods.
|
|
430
497
|
invalidate();
|
|
@@ -449,7 +516,7 @@ export class Runtime {
|
|
|
449
516
|
if (script.state === 0 || (retry && script.state === 3)) {
|
|
450
517
|
script.state = 1;
|
|
451
518
|
try {
|
|
452
|
-
script.desc.init(this.empty,
|
|
519
|
+
script.desc.init(this.empty, this.scriptSuper).call(g);
|
|
453
520
|
}
|
|
454
521
|
catch (e) {
|
|
455
522
|
script.state = 3;
|
|
@@ -490,6 +557,7 @@ export class Runtime {
|
|
|
490
557
|
scope(outer, locals, withs) {
|
|
491
558
|
const chain = outer.concat(locals);
|
|
492
559
|
chain.w = outer.w | (withs << outer.length);
|
|
560
|
+
chain.found = undefined;
|
|
493
561
|
return chain;
|
|
494
562
|
}
|
|
495
563
|
/**
|
|
@@ -504,6 +572,7 @@ export class Runtime {
|
|
|
504
572
|
const packed = chain.slice(0, at);
|
|
505
573
|
packed.push(new ScopePack(chain.slice(at), chain.w >>> at));
|
|
506
574
|
packed.w = (chain.w & ((1 << at) - 1)) | (1 << at);
|
|
575
|
+
packed.found = undefined;
|
|
507
576
|
return packed;
|
|
508
577
|
}
|
|
509
578
|
/**
|
|
@@ -532,6 +601,40 @@ export class Runtime {
|
|
|
532
601
|
return locals[i];
|
|
533
602
|
}
|
|
534
603
|
}
|
|
604
|
+
const found = this.outerScopeOf(outer, mn);
|
|
605
|
+
if (found !== null) {
|
|
606
|
+
return found;
|
|
607
|
+
}
|
|
608
|
+
return this.global(mn, outer.length ? outer[0] : locals[0], strict);
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* The innermost object of a captured chain that has `mn`, or null: kept
|
|
612
|
+
* on a chain without a with scope (ScopeFinds), as a function whose
|
|
613
|
+
* chain the compiler could not type, such as one made where chains of
|
|
614
|
+
* different lengths meet, looks its names up each time it runs.
|
|
615
|
+
*/
|
|
616
|
+
outerScopeOf(outer, mn) {
|
|
617
|
+
let finds = outer.found;
|
|
618
|
+
if (finds === undefined) {
|
|
619
|
+
finds = hasWith(outer, outer.w) ? null : new ScopeFinds();
|
|
620
|
+
outer.found = finds;
|
|
621
|
+
}
|
|
622
|
+
// A name made at run time is a new one each time: keeping it would only grow the map.
|
|
623
|
+
if (finds === null || mn.cache === NO_CACHE) {
|
|
624
|
+
return this.searchOuter(outer, mn);
|
|
625
|
+
}
|
|
626
|
+
if (finds.epoch !== epoch()) {
|
|
627
|
+
finds.clear();
|
|
628
|
+
finds.epoch = epoch();
|
|
629
|
+
}
|
|
630
|
+
let o = finds.get(mn);
|
|
631
|
+
if (o === undefined) {
|
|
632
|
+
o = this.searchOuter(outer, mn);
|
|
633
|
+
finds.set(mn, o);
|
|
634
|
+
}
|
|
635
|
+
return o;
|
|
636
|
+
}
|
|
637
|
+
searchOuter(outer, mn) {
|
|
535
638
|
for (let i = outer.length - 1; i >= 0; i--) {
|
|
536
639
|
const o = outer[i];
|
|
537
640
|
if (o instanceof ScopePack) {
|
|
@@ -544,7 +647,7 @@ export class Runtime {
|
|
|
544
647
|
return o;
|
|
545
648
|
}
|
|
546
649
|
}
|
|
547
|
-
return
|
|
650
|
+
return null;
|
|
548
651
|
}
|
|
549
652
|
findPropertyStrict(mn, outer, locals, withs) {
|
|
550
653
|
return this.findProperty(mn, outer, locals, withs, true);
|
|
@@ -669,15 +772,22 @@ export class Runtime {
|
|
|
669
772
|
traitsOf(v) {
|
|
670
773
|
switch (typeof v) {
|
|
671
774
|
case "object":
|
|
672
|
-
case "function":
|
|
775
|
+
case "function": {
|
|
673
776
|
if (v === null) {
|
|
674
777
|
throw this.error("TypeError", 1009);
|
|
675
778
|
}
|
|
779
|
+
// An object's own first: instanceof walks the whole prototype
|
|
780
|
+
// chain of an object, and a class's is as deep as its bases.
|
|
781
|
+
const traits = v.$traits;
|
|
782
|
+
if (traits !== undefined) {
|
|
783
|
+
return traits;
|
|
784
|
+
}
|
|
676
785
|
return v instanceof FloatValue
|
|
677
786
|
? this.builtinTraits("float")
|
|
678
787
|
: v instanceof Namespace
|
|
679
788
|
? this.builtinTraits("Namespace")
|
|
680
|
-
:
|
|
789
|
+
: traits;
|
|
790
|
+
}
|
|
681
791
|
// As avmplus' toVTable: every number is a Number at run time, int or
|
|
682
792
|
// not; int's and uint's traits only bind early, from static types.
|
|
683
793
|
case "number":
|
|
@@ -698,12 +808,17 @@ export class Runtime {
|
|
|
698
808
|
receiverTraits(v) {
|
|
699
809
|
switch (typeof v) {
|
|
700
810
|
case "object":
|
|
701
|
-
case "function":
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
811
|
+
case "function": {
|
|
812
|
+
if (v === null) {
|
|
813
|
+
return undefined;
|
|
814
|
+
}
|
|
815
|
+
// A float and a Namespace have none of their own (see traitsOf).
|
|
816
|
+
const traits = v.$traits;
|
|
817
|
+
if (traits !== undefined) {
|
|
818
|
+
return traits;
|
|
819
|
+
}
|
|
820
|
+
return v instanceof FloatValue ? this.builtinTraits("float") : undefined;
|
|
821
|
+
}
|
|
707
822
|
case "string":
|
|
708
823
|
return this.stringTraits;
|
|
709
824
|
case "number":
|
|
@@ -840,7 +955,7 @@ export class Runtime {
|
|
|
840
955
|
mn.kind === CONSTANT_MultinameA ||
|
|
841
956
|
mn.kind === CONSTANT_MultinameL ||
|
|
842
957
|
mn.kind === CONSTANT_MultinameLA);
|
|
843
|
-
throw this.error("ReferenceError", name === null && nsset ? 1081 : 1069, mn.name ?? "*", traits.
|
|
958
|
+
throw this.error("ReferenceError", name === null && nsset ? 1081 : 1069, mn.name ?? "*", traits.errorName);
|
|
844
959
|
}
|
|
845
960
|
/**
|
|
846
961
|
* obj[i] for a number i, as avmplus' getUintProperty: a Vector's,
|
|
@@ -877,7 +992,7 @@ export class Runtime {
|
|
|
877
992
|
}
|
|
878
993
|
}
|
|
879
994
|
}
|
|
880
|
-
return this.getProperty(o, this.
|
|
995
|
+
return this.getProperty(o, this.indexName(mn, i));
|
|
881
996
|
}
|
|
882
997
|
/** obj[i] = v for a number i, as avmplus' setUintProperty. */
|
|
883
998
|
setIndexed(o, mn, i, v) {
|
|
@@ -889,12 +1004,114 @@ export class Runtime {
|
|
|
889
1004
|
traits.setIndex(o, i, v, this);
|
|
890
1005
|
return;
|
|
891
1006
|
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
1007
|
+
const a = o.$a;
|
|
1008
|
+
if (a !== undefined) {
|
|
1009
|
+
if (a !== SEALED_ELEMENTS && i !== 0xffffffff) {
|
|
1010
|
+
a[i] = v;
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
else if (traits?.dynamic && traits.properties === null && !traits.refusesNames) {
|
|
1015
|
+
// As ScriptObject::setUintProperty: an object with no elements of its own keeps the
|
|
1016
|
+
// number among its dynamic properties, with no binding asked for.
|
|
1017
|
+
const d = o.$d;
|
|
1018
|
+
if (d) {
|
|
1019
|
+
d.set(`${i}`, v);
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
this.setProperty(o, this.indexName(mn, i), v);
|
|
1025
|
+
}
|
|
1026
|
+
/**
|
|
1027
|
+
* obj[k] by a runtime name with no public namespace, or an attribute's,
|
|
1028
|
+
* in a script's or a class's initializer, which avmplus interprets: its
|
|
1029
|
+
* getproperty reads an int key of at least 0 off an object by
|
|
1030
|
+
* getUintProperty, whatever namespaces the name has, where its JIT asks
|
|
1031
|
+
* for a public one (getIndexed). Any other key makes a name.
|
|
1032
|
+
*/
|
|
1033
|
+
getInterpreted(o, mn, k) {
|
|
1034
|
+
if (uintAtom(k) && isScriptObject(o)) {
|
|
1035
|
+
return this.getIndexed(o, ELEMENT_NAME, k);
|
|
1036
|
+
}
|
|
1037
|
+
return this.getProperty(o, this.runtimeName(mn, k));
|
|
1038
|
+
}
|
|
1039
|
+
/** obj[k] = v as getInterpreted reads it, as avmplus' interpreter's setproperty. */
|
|
1040
|
+
setInterpreted(o, mn, k, v) {
|
|
1041
|
+
if (uintAtom(k) && isScriptObject(o)) {
|
|
1042
|
+
this.setIndexed(o, ELEMENT_NAME, k, v);
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
this.setProperty(o, this.runtimeName(mn, k), v);
|
|
1046
|
+
}
|
|
1047
|
+
/**
|
|
1048
|
+
* obj[k] for a key whose type the compiler does not know, by a name with
|
|
1049
|
+
* no namespace from the stack, as avmplus' getprop_index and
|
|
1050
|
+
* getpropertyHelper: a number is an index (getIndexed), an object a
|
|
1051
|
+
* Dictionary has as a key is read by itself, and anything else, a QName
|
|
1052
|
+
* and a Dictionary's absent key among them, is looked up by the name it
|
|
1053
|
+
* makes.
|
|
1054
|
+
*/
|
|
1055
|
+
getKeyed(o, mn, k) {
|
|
1056
|
+
let r;
|
|
1057
|
+
if (typeof k === "number") {
|
|
1058
|
+
r = this.getIndexed(o, mn, k);
|
|
1059
|
+
return r;
|
|
1060
|
+
}
|
|
1061
|
+
if (typeof k === "object" && k !== null) {
|
|
1062
|
+
const keys = o?.$keys;
|
|
1063
|
+
if (keys !== undefined) {
|
|
1064
|
+
if (!mn.elementName) {
|
|
1065
|
+
r = this.getProperty(o, this.runtimeName(mn, this.unkeyed(k)));
|
|
1066
|
+
return r;
|
|
1067
|
+
}
|
|
1068
|
+
// What is there was put there by a name with the object as its key, which a QName's is not.
|
|
1069
|
+
const v = keys.get(k);
|
|
1070
|
+
if (v !== undefined) {
|
|
1071
|
+
return v;
|
|
1072
|
+
}
|
|
895
1073
|
}
|
|
896
1074
|
}
|
|
897
|
-
this.
|
|
1075
|
+
r = this.getProperty(o, this.runtimeName(mn, k));
|
|
1076
|
+
return r;
|
|
1077
|
+
}
|
|
1078
|
+
/**
|
|
1079
|
+
* An object given as the key of a Dictionary by a name with no public
|
|
1080
|
+
* namespace, as the name is made of it: avmplus' JIT asks a Dictionary
|
|
1081
|
+
* for an object only through getprop_index and setprop_index, which such
|
|
1082
|
+
* a name does not reach, so the object is its string, as on any other
|
|
1083
|
+
* receiver (initMultinameLate); a QName names what it names. Its
|
|
1084
|
+
* interpreter asks the Dictionary by any name, as a name made without
|
|
1085
|
+
* this does: the compiler leaves script and class initializers to that.
|
|
1086
|
+
*/
|
|
1087
|
+
unkeyed(k) {
|
|
1088
|
+
return k.$traits !== undefined && k.$local === undefined ? this.toString(k) : k;
|
|
1089
|
+
}
|
|
1090
|
+
/** obj[k] = v for a key whose type the compiler does not know, as avmplus' setprop_index and setpropertyHelper. */
|
|
1091
|
+
setKeyed(o, mn, k, v) {
|
|
1092
|
+
if (typeof k === "number") {
|
|
1093
|
+
this.setIndexed(o, mn, k, v);
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
if (typeof k === "object" && k !== null) {
|
|
1097
|
+
const keys = o?.$keys;
|
|
1098
|
+
if (keys !== undefined) {
|
|
1099
|
+
if (!mn.elementName) {
|
|
1100
|
+
this.setProperty(o, this.runtimeName(mn, this.unkeyed(k)), v);
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
if (keys.replace(k, v)) {
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
// A new key: an object of traits, which a float and a Namespace are not, and no QName,
|
|
1107
|
+
// which names what it names. Those are added, or not, by the name they make.
|
|
1108
|
+
if (k.$traits !== undefined && k.$local === undefined) {
|
|
1109
|
+
keys.add(k, v);
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
this.setProperty(o, this.runtimeName(mn, k), v);
|
|
898
1115
|
}
|
|
899
1116
|
/**
|
|
900
1117
|
* Element i of Vector o set to x, already converted, as
|
|
@@ -1084,18 +1301,16 @@ export class Runtime {
|
|
|
1084
1301
|
if (slot !== undefined) {
|
|
1085
1302
|
return o[slot];
|
|
1086
1303
|
}
|
|
1087
|
-
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.
|
|
1304
|
+
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.errorName);
|
|
1088
1305
|
}
|
|
1089
1306
|
default:
|
|
1090
|
-
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.
|
|
1307
|
+
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.errorName);
|
|
1091
1308
|
}
|
|
1092
1309
|
}
|
|
1093
1310
|
/** fillCache (cache-fill.ts), for a name that caches on traits a cache knows `o` by. */
|
|
1094
1311
|
fill(o, traits, b, mn) {
|
|
1095
1312
|
const head = mn.cache;
|
|
1096
|
-
if (head === NO_CACHE ||
|
|
1097
|
-
(head.replaced === REPLACEMENTS && head.epoch === epoch()) ||
|
|
1098
|
-
this.receiverTraits(o) !== traits) {
|
|
1313
|
+
if (head === NO_CACHE || this.receiverTraits(o) !== traits) {
|
|
1099
1314
|
return;
|
|
1100
1315
|
}
|
|
1101
1316
|
fillCache(head, o, traits, b, mn);
|
|
@@ -1124,6 +1339,8 @@ export class Runtime {
|
|
|
1124
1339
|
f.$length = method.$length ?? method.length;
|
|
1125
1340
|
f.$id = method.$id ?? 0;
|
|
1126
1341
|
f.$closure = true;
|
|
1342
|
+
// Whose method it is, for moduleOf.
|
|
1343
|
+
f.$of = traits;
|
|
1127
1344
|
if (typeof o === "object") {
|
|
1128
1345
|
byMethod.set(method, f);
|
|
1129
1346
|
}
|
|
@@ -1176,7 +1393,7 @@ export class Runtime {
|
|
|
1176
1393
|
switch (b & 7) {
|
|
1177
1394
|
case BIND_Const:
|
|
1178
1395
|
if (!init) {
|
|
1179
|
-
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.
|
|
1396
|
+
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.errorName);
|
|
1180
1397
|
}
|
|
1181
1398
|
o[slotKey(id)] = this.coerce(v, traits.slotType(id));
|
|
1182
1399
|
return;
|
|
@@ -1188,9 +1405,9 @@ export class Runtime {
|
|
|
1188
1405
|
(traits.proto[untypedSetKey(id + 1)] ?? traits.proto[methodKey(id + 1)]).call(o, v);
|
|
1189
1406
|
return;
|
|
1190
1407
|
case BIND_Method:
|
|
1191
|
-
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.
|
|
1408
|
+
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.errorName);
|
|
1192
1409
|
default:
|
|
1193
|
-
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.
|
|
1410
|
+
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.errorName);
|
|
1194
1411
|
}
|
|
1195
1412
|
}
|
|
1196
1413
|
const name = mn.dynamicName();
|
|
@@ -1212,7 +1429,7 @@ export class Runtime {
|
|
|
1212
1429
|
return;
|
|
1213
1430
|
}
|
|
1214
1431
|
}
|
|
1215
|
-
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.
|
|
1432
|
+
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.errorName);
|
|
1216
1433
|
}
|
|
1217
1434
|
initProperty(o, mn, v) {
|
|
1218
1435
|
this.setProperty(o, mn, v, true);
|
|
@@ -1227,7 +1444,7 @@ export class Runtime {
|
|
|
1227
1444
|
}
|
|
1228
1445
|
// A primitive's property cannot be deleted, as MethodEnv's delproperty has it.
|
|
1229
1446
|
if (typeof o !== "object" || o instanceof Namespace) {
|
|
1230
|
-
throw this.error("ReferenceError", 1120, mn.name ?? "*", this.traitsOf(o).
|
|
1447
|
+
throw this.error("ReferenceError", 1120, mn.name ?? "*", this.traitsOf(o).errorName);
|
|
1231
1448
|
}
|
|
1232
1449
|
// E4X 11.3.1: delete x[list] is a TypeError, as in delete x.a.(b == 1).
|
|
1233
1450
|
if (mn.key?.$nodes !== undefined) {
|
|
@@ -1388,8 +1605,7 @@ export class Runtime {
|
|
|
1388
1605
|
// A namespace is the runtime's own object: its prototype is its class's.
|
|
1389
1606
|
if (typeof o === "object" &&
|
|
1390
1607
|
o !== null &&
|
|
1391
|
-
!(o instanceof Namespace)
|
|
1392
|
-
!(o instanceof FloatValue)) {
|
|
1608
|
+
(o.$traits !== undefined || !(o instanceof Namespace || o instanceof FloatValue))) {
|
|
1393
1609
|
return o.$p;
|
|
1394
1610
|
}
|
|
1395
1611
|
return this.traitsOf(o).proto.$p;
|
|
@@ -1402,6 +1618,28 @@ export class Runtime {
|
|
|
1402
1618
|
publicName(name) {
|
|
1403
1619
|
return qname(publicNs, this.nameString(name));
|
|
1404
1620
|
}
|
|
1621
|
+
// Natives' typed reach into AS3 objects (as3-types.ts): getProperty,
|
|
1622
|
+
// setProperty and callProperty of the public name, the lookup natives
|
|
1623
|
+
// made before, with the name checked against the class's declarations
|
|
1624
|
+
// when compiled.
|
|
1625
|
+
/** `o`'s public property `name`: a variable, constant or accessor its class declares. */
|
|
1626
|
+
prop(o, name) {
|
|
1627
|
+
// biome-ignore lint/style/useConst: a const is folded into a tail call (see getProperty)
|
|
1628
|
+
let r;
|
|
1629
|
+
r = this.getProperty(o, this.publicName(name));
|
|
1630
|
+
return r;
|
|
1631
|
+
}
|
|
1632
|
+
/** Sets `o`'s public property `name`, which its class declares writable. */
|
|
1633
|
+
setProp(o, name, v) {
|
|
1634
|
+
this.setProperty(o, this.publicName(name), v);
|
|
1635
|
+
}
|
|
1636
|
+
/** Calls `o`'s public method `name` with `args`. */
|
|
1637
|
+
callProp(o, name, ...args) {
|
|
1638
|
+
// biome-ignore lint/style/useConst: a const is folded into a tail call (see getProperty)
|
|
1639
|
+
let r;
|
|
1640
|
+
r = this.callProperty(o, this.publicName(name), ...args);
|
|
1641
|
+
return r;
|
|
1642
|
+
}
|
|
1405
1643
|
/** A property name as a string, as ToString makes one. */
|
|
1406
1644
|
nameString(name) {
|
|
1407
1645
|
return typeof name === "string" ? name : this.toString(name);
|
|
@@ -1615,8 +1853,30 @@ export class Runtime {
|
|
|
1615
1853
|
}
|
|
1616
1854
|
return key;
|
|
1617
1855
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1856
|
+
/**
|
|
1857
|
+
* The first method each factory made for a class's or a script's
|
|
1858
|
+
* traits, as avmplus' AbcEnv keeps the first MethodEnv of each method
|
|
1859
|
+
* a vtable makes (VTable::makeMethodEnv): what callstatic calls.
|
|
1860
|
+
*/
|
|
1861
|
+
staticMethods = new WeakMap();
|
|
1862
|
+
/** Keep `method`, made by `factory`, for callstatic, unless it made one before. */
|
|
1863
|
+
keepStatic(factory, method) {
|
|
1864
|
+
if (!this.staticMethods.has(factory)) {
|
|
1865
|
+
this.staticMethods.set(factory, method);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
/**
|
|
1869
|
+
* callstatic: method `factory` made, called on `o` with its arguments,
|
|
1870
|
+
* which the compiler coerced. avmplus verifies a method when it first
|
|
1871
|
+
* runs and refuses one that calls a method no vtable has made yet
|
|
1872
|
+
* (1107); that is found here only once the call is reached.
|
|
1873
|
+
*/
|
|
1874
|
+
callStatic(factory, o, ...args) {
|
|
1875
|
+
const method = this.staticMethods.get(factory);
|
|
1876
|
+
if (method === undefined) {
|
|
1877
|
+
throw this.error("VerifyError", 1107);
|
|
1878
|
+
}
|
|
1879
|
+
return method.apply(o, args);
|
|
1620
1880
|
}
|
|
1621
1881
|
// The super operations, as MethodEnv's: by the base class's traits
|
|
1622
1882
|
// alone, a name they do not bind a ReferenceError, not a dynamic property.
|
|
@@ -1629,7 +1889,7 @@ export class Runtime {
|
|
|
1629
1889
|
return r;
|
|
1630
1890
|
}
|
|
1631
1891
|
if (b === 0) {
|
|
1632
|
-
throw this.error("ReferenceError", 1070, mn.name ?? "*", traits.
|
|
1892
|
+
throw this.error("ReferenceError", 1070, mn.name ?? "*", traits.errorName);
|
|
1633
1893
|
}
|
|
1634
1894
|
r = this.callValue(this.getBound(o, traits, b, mn), o, args, mn);
|
|
1635
1895
|
return r;
|
|
@@ -1638,7 +1898,7 @@ export class Runtime {
|
|
|
1638
1898
|
const traits = sup.$it;
|
|
1639
1899
|
const b = traits.find(mn);
|
|
1640
1900
|
if (b === 0) {
|
|
1641
|
-
throw this.error("ReferenceError", 1069, mn.name ?? "*", traits.
|
|
1901
|
+
throw this.error("ReferenceError", 1069, mn.name ?? "*", traits.errorName);
|
|
1642
1902
|
}
|
|
1643
1903
|
return this.getBound(o, traits, b, mn);
|
|
1644
1904
|
}
|
|
@@ -1655,11 +1915,11 @@ export class Runtime {
|
|
|
1655
1915
|
o[slotKey(id)] = this.coerce(v, traits.slotType(id));
|
|
1656
1916
|
return;
|
|
1657
1917
|
case BIND_Method:
|
|
1658
|
-
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.
|
|
1918
|
+
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.errorName);
|
|
1659
1919
|
case 0:
|
|
1660
|
-
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.
|
|
1920
|
+
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.errorName);
|
|
1661
1921
|
default:
|
|
1662
|
-
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.
|
|
1922
|
+
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.errorName);
|
|
1663
1923
|
}
|
|
1664
1924
|
}
|
|
1665
1925
|
constructSuper(sup, o, ...args) {
|
|
@@ -1809,6 +2069,19 @@ export class Runtime {
|
|
|
1809
2069
|
this.functionObjects.set(method, f);
|
|
1810
2070
|
return f;
|
|
1811
2071
|
}
|
|
2072
|
+
/**
|
|
2073
|
+
* The module a function's code is from, as avmplus has a method's code
|
|
2074
|
+
* context: a function's by the global object its scope begins with, a
|
|
2075
|
+
* bound method's by its receiver's class; null for a native, a class's
|
|
2076
|
+
* own method, or anything but a function.
|
|
2077
|
+
*/
|
|
2078
|
+
moduleOf(f) {
|
|
2079
|
+
const o = f;
|
|
2080
|
+
if (o?.$of) {
|
|
2081
|
+
return o.$of.abc;
|
|
2082
|
+
}
|
|
2083
|
+
return o?.$global ? this.traitsOf(o.$global).abc : null;
|
|
2084
|
+
}
|
|
1812
2085
|
/** A Function object calling `f`, with `global` as its receiver when it has none. */
|
|
1813
2086
|
newFunctionObject(f, global) {
|
|
1814
2087
|
const o = this.functionTraits.instance();
|
|
@@ -2044,7 +2317,7 @@ export class Runtime {
|
|
|
2044
2317
|
if (v.$traits === traits || this.isInstanceOf(v, traits)) {
|
|
2045
2318
|
return v;
|
|
2046
2319
|
}
|
|
2047
|
-
throw this.error("TypeError", 1034, this.describe(v), traits.
|
|
2320
|
+
throw this.error("TypeError", 1034, this.describe(v), traits.errorName);
|
|
2048
2321
|
}
|
|
2049
2322
|
}
|
|
2050
2323
|
}
|
|
@@ -2065,7 +2338,7 @@ export class Runtime {
|
|
|
2065
2338
|
if (v.$traits === traits || this.isInstanceOf(v, traits)) {
|
|
2066
2339
|
return v;
|
|
2067
2340
|
}
|
|
2068
|
-
throw this.error("TypeError", 1034, this.describe(v), traits.
|
|
2341
|
+
throw this.error("TypeError", 1034, this.describe(v), traits.errorName);
|
|
2069
2342
|
}
|
|
2070
2343
|
coerceString(v) {
|
|
2071
2344
|
return v === null || v === undefined ? null : typeof v === "string" ? v : this.toString(v);
|
|
@@ -2264,7 +2537,7 @@ export class Runtime {
|
|
|
2264
2537
|
return v;
|
|
2265
2538
|
}
|
|
2266
2539
|
}
|
|
2267
|
-
throw this.error("TypeError", 1050, o.$traits.
|
|
2540
|
+
throw this.error("TypeError", 1050, o.$traits.errorName);
|
|
2268
2541
|
}
|
|
2269
2542
|
add(a, b) {
|
|
2270
2543
|
if (typeof a === "number" && typeof b === "number") {
|
|
@@ -2543,12 +2816,21 @@ export class Runtime {
|
|
|
2543
2816
|
catch {
|
|
2544
2817
|
return new AsError(`${name}: ${message}`);
|
|
2545
2818
|
}
|
|
2546
|
-
|
|
2819
|
+
const made = this.constructClass(cls, [message, id]);
|
|
2820
|
+
// What the number stands for, kept beside the message for a host's report (detailOf).
|
|
2821
|
+
if (!this.debugger) {
|
|
2822
|
+
Object.defineProperty(made, "$detail", { value: errorMessage(true, id, args) });
|
|
2823
|
+
}
|
|
2824
|
+
return made;
|
|
2547
2825
|
}
|
|
2548
2826
|
/** See stackOf in errors.ts. */
|
|
2549
2827
|
stackOf(error) {
|
|
2550
2828
|
return stackOf(error);
|
|
2551
2829
|
}
|
|
2830
|
+
/** See detailOf in errors.ts. */
|
|
2831
|
+
detailOf(error) {
|
|
2832
|
+
return detailOf(error);
|
|
2833
|
+
}
|
|
2552
2834
|
/** See errorMessage in errors.ts. */
|
|
2553
2835
|
errorMessage(id, args = []) {
|
|
2554
2836
|
return errorMessage(this.debugger, id, args);
|
|
@@ -2573,11 +2855,35 @@ export class Runtime {
|
|
|
2573
2855
|
if (isViewRangeError(e)) {
|
|
2574
2856
|
return this.error("RangeError", 1506);
|
|
2575
2857
|
}
|
|
2858
|
+
if (e instanceof UnsupportedError) {
|
|
2859
|
+
return this.unsupportedCaught(e);
|
|
2860
|
+
}
|
|
2576
2861
|
if (e instanceof Error && !(e instanceof AsError)) {
|
|
2577
2862
|
throw e;
|
|
2578
2863
|
}
|
|
2579
2864
|
return e;
|
|
2580
2865
|
}
|
|
2866
|
+
/** What a catch was told of already (unsupportedCaught). */
|
|
2867
|
+
unsupportedTold = new Set();
|
|
2868
|
+
/**
|
|
2869
|
+
* What is not supported as the AS3 error a catch gets: an
|
|
2870
|
+
* IllegalOperationError with its message, or an Error where the player's
|
|
2871
|
+
* classes are not loaded; said once to the host, as the code may say nothing.
|
|
2872
|
+
*/
|
|
2873
|
+
unsupportedCaught(e) {
|
|
2874
|
+
if (!this.unsupportedTold.has(e.message)) {
|
|
2875
|
+
this.unsupportedTold.add(e.message);
|
|
2876
|
+
this.onUnsupported?.(e.message);
|
|
2877
|
+
}
|
|
2878
|
+
let cls;
|
|
2879
|
+
try {
|
|
2880
|
+
cls = this.resolve(this.cls(namespace(NS_Public, "flash.errors"), "IllegalOperationError"));
|
|
2881
|
+
}
|
|
2882
|
+
catch {
|
|
2883
|
+
cls = this.builtinClass("Error");
|
|
2884
|
+
}
|
|
2885
|
+
return this.constructClass(cls, [e.message, 0]);
|
|
2886
|
+
}
|
|
2581
2887
|
catches(e, type) {
|
|
2582
2888
|
return this.isInstanceOf(e, this.traitsOfType(type));
|
|
2583
2889
|
}
|
|
@@ -2585,7 +2891,7 @@ export class Runtime {
|
|
|
2585
2891
|
return new Error("swf2es: a dispatcher reached no block");
|
|
2586
2892
|
}
|
|
2587
2893
|
unsupported(what) {
|
|
2588
|
-
return new
|
|
2894
|
+
return new UnsupportedError(`swf2es: ${what} is not supported yet`);
|
|
2589
2895
|
}
|
|
2590
2896
|
// Class aliases and the classes AMF makes (amf-classes.ts).
|
|
2591
2897
|
registerClassAlias(name, cls) {
|