@swf2es/runtime 0.1.16 → 0.1.18
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/classes.d.ts.map +1 -1
- package/dist/avm2/classes.js +10 -3
- package/dist/avm2/classes.js.map +1 -1
- package/dist/avm2/errors.d.ts.map +1 -1
- package/dist/avm2/errors.js +3 -1
- package/dist/avm2/errors.js.map +1 -1
- package/dist/avm2/index.d.ts +3 -0
- package/dist/avm2/index.d.ts.map +1 -1
- package/dist/avm2/index.js +2 -0
- package/dist/avm2/index.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/vector.js +1 -1
- package/dist/avm2/natives/vector.js.map +1 -1
- package/dist/avm2/runtime.d.ts +44 -1
- package/dist/avm2/runtime.d.ts.map +1 -1
- package/dist/avm2/runtime.js +119 -20
- package/dist/avm2/runtime.js.map +1 -1
- package/dist/avm2/traits.d.ts +6 -0
- package/dist/avm2/traits.d.ts.map +1 -1
- package/dist/avm2/traits.js +17 -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/classes.ts +10 -3
- package/src/avm2/errors.ts +3 -1
- package/src/avm2/index.ts +5 -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/vector.ts +1 -1
- package/src/avm2/runtime.ts +141 -27
- package/src/avm2/traits.ts +20 -0
|
@@ -760,13 +760,11 @@ export function byteArrayNatives(rt: Runtime): Natives {
|
|
|
760
760
|
return rt.defaultObjectEncoding;
|
|
761
761
|
}
|
|
762
762
|
|
|
763
|
+
// Unchecked, unlike an instance's: avmshell and Flash take any uint, a
|
|
764
|
+
// new ByteArray starts with it, and writeObject reads an encoding below
|
|
765
|
+
// 3 as AMF0 (#1508 in avmshell), any other as AMF3.
|
|
763
766
|
static set defaultObjectEncoding(v: Value) {
|
|
764
|
-
|
|
765
|
-
if (e !== kAMF0 && e !== kAMF3) {
|
|
766
|
-
throw rt.error("ArgumentError", 2008, "objectEncoding");
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
rt.defaultObjectEncoding = e;
|
|
767
|
+
rt.defaultObjectEncoding = rt.toUint(v);
|
|
770
768
|
}
|
|
771
769
|
|
|
772
770
|
get length() {
|
|
@@ -1215,13 +1213,11 @@ export function byteArrayNatives(rt: Runtime): Natives {
|
|
|
1215
1213
|
},
|
|
1216
1214
|
};
|
|
1217
1215
|
|
|
1216
|
+
// AMF3 whatever their objectEncoding, as ObjectOutputObject::writeObject
|
|
1217
|
+
// and ObjectInputObject::readObject: avmshell and Flash alike.
|
|
1218
1218
|
class ObjectOutputNatives {
|
|
1219
1219
|
writeObject(this: AsObject, v: Value): void {
|
|
1220
1220
|
const stream: Writer = this.$amf;
|
|
1221
|
-
if (stream.objectEncoding !== 3) {
|
|
1222
|
-
throw rt.unsupported("AMF0");
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
1221
|
stream.value(v);
|
|
1226
1222
|
}
|
|
1227
1223
|
}
|
|
@@ -1229,10 +1225,6 @@ export function byteArrayNatives(rt: Runtime): Natives {
|
|
|
1229
1225
|
class ObjectInputNatives {
|
|
1230
1226
|
readObject(this: AsObject): Value {
|
|
1231
1227
|
const stream: Reader = this.$amf;
|
|
1232
|
-
if (stream.objectEncoding !== 3) {
|
|
1233
|
-
throw rt.unsupported("AMF0");
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
1228
|
return stream.value();
|
|
1237
1229
|
}
|
|
1238
1230
|
|
|
@@ -121,7 +121,14 @@ function chooseTraits(rt: Runtime, v: Value): Traits | string {
|
|
|
121
121
|
return "null";
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
// An int atom: -0 is a double.
|
|
125
|
+
if (
|
|
126
|
+
typeof v === "number" &&
|
|
127
|
+
(v | 0) === v &&
|
|
128
|
+
v >= -(1 << 28) &&
|
|
129
|
+
v < 1 << 28 &&
|
|
130
|
+
!Object.is(v, -0)
|
|
131
|
+
) {
|
|
125
132
|
return rt.traitsOfType("int");
|
|
126
133
|
}
|
|
127
134
|
|
|
@@ -191,9 +191,12 @@ function shortName(qualified: string): string {
|
|
|
191
191
|
|
|
192
192
|
export function qualifiedClassName(rt: Runtime, v: Value): string {
|
|
193
193
|
switch (typeof v) {
|
|
194
|
-
// As TypeDescriber::chooseTraits: an int is one that fits avmplus' 29-bit
|
|
194
|
+
// As TypeDescriber::chooseTraits: an int is one that fits avmplus' 29-bit
|
|
195
|
+
// int atom, which -0, always a double, never is.
|
|
195
196
|
case "number":
|
|
196
|
-
return (v | 0) === v && v >= -(1 << 28) && v < 1 << 28
|
|
197
|
+
return (v | 0) === v && v >= -(1 << 28) && v < 1 << 28 && !Object.is(v, -0)
|
|
198
|
+
? "int"
|
|
199
|
+
: "Number";
|
|
197
200
|
case "string":
|
|
198
201
|
return "String";
|
|
199
202
|
case "boolean":
|
|
@@ -330,7 +330,7 @@ for (const [kind, convert, fill, elementsOf, store] of VECTORS) {
|
|
|
330
330
|
|
|
331
331
|
const source = args[0];
|
|
332
332
|
if (!isObject(source)) {
|
|
333
|
-
throw rt.error("TypeError", 1034, rt.describe(source), cls.$it.
|
|
333
|
+
throw rt.error("TypeError", 1034, rt.describe(source), cls.$it.errorName);
|
|
334
334
|
}
|
|
335
335
|
|
|
336
336
|
if (source.$traits === cls.$it) {
|
package/src/avm2/runtime.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { API_VERSION, checkApiVersion } from "@swf2es/format";
|
|
15
15
|
import { AmfClasses } from "./amf-classes.js";
|
|
16
16
|
import { ArrayConversion } from "./array-conversion.js";
|
|
17
|
+
import type { MethodName, PropertyName, Ref, WritableName } from "./as3-types.js";
|
|
17
18
|
import { fillCache } from "./cache-fill.js";
|
|
18
19
|
import { newClass, specializeVector, withId } from "./classes.js";
|
|
19
20
|
import { classNamed, classNamedByCode, definingAbc, definitionNamed } from "./definitions.js";
|
|
@@ -168,6 +169,21 @@ function hasWith(scopes: Value[], w: number): boolean {
|
|
|
168
169
|
}
|
|
169
170
|
|
|
170
171
|
/** The value of `o`'s dynamic property `name`, or NOT_FOUND. */
|
|
172
|
+
/** 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. */
|
|
173
|
+
function uintAtom(k: Value): k is number {
|
|
174
|
+
return typeof k === "number" && k >>> 0 === k && (k !== 0 || 1 / k > 0);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Whether v is an object's atom to avmplus: not null, nor a Namespace or float, whose atoms are their own. */
|
|
178
|
+
function isScriptObject(v: Value): boolean {
|
|
179
|
+
return (
|
|
180
|
+
typeof v === "object" && v !== null && !(v instanceof Namespace) && !(v instanceof FloatValue)
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** The name avmplus' getUintProperty looks a number up by: public, at every version. */
|
|
185
|
+
const ELEMENT_NAME = new Multiname(CONSTANT_MultinameL, [publicNs], [255], null, false);
|
|
186
|
+
|
|
171
187
|
function dynamicValue(o: AsObject, name: string): Value {
|
|
172
188
|
const d: Map<string, Value> | null | undefined = o.$d;
|
|
173
189
|
if (!d) {
|
|
@@ -244,6 +260,13 @@ export class Runtime {
|
|
|
244
260
|
/** The builtin classes' traits, made before their classes so the bootstrap can refer to them. */
|
|
245
261
|
readonly objectTraits: Traits;
|
|
246
262
|
readonly classTraits: Traits;
|
|
263
|
+
/**
|
|
264
|
+
* What the super operations of a script's methods and of a class's
|
|
265
|
+
* static ones look in, as avmplus' script traits extend Object and a
|
|
266
|
+
* class object's traits Class: their `super` is that class's instance.
|
|
267
|
+
*/
|
|
268
|
+
readonly scriptSuper: AsObject;
|
|
269
|
+
readonly staticSuper: AsObject;
|
|
247
270
|
readonly functionTraits: Traits;
|
|
248
271
|
/**
|
|
249
272
|
* Method closures, by receiver and method, so that o.f === o.f; by the
|
|
@@ -299,6 +322,8 @@ export class Runtime {
|
|
|
299
322
|
this.objectTraits.dynamic = true;
|
|
300
323
|
this.objectTraits.testsValues = true;
|
|
301
324
|
this.classTraits = new Traits("Class", this.objectTraits);
|
|
325
|
+
this.scriptSuper = { $it: this.objectTraits };
|
|
326
|
+
this.staticSuper = { $it: this.classTraits };
|
|
302
327
|
this.functionTraits = new Traits("Function", this.objectTraits);
|
|
303
328
|
this.functionTraits.dynamic = true;
|
|
304
329
|
this.natives = typeof natives === "function" ? natives(this) : natives;
|
|
@@ -640,14 +665,9 @@ export class Runtime {
|
|
|
640
665
|
// indexes the scopes their closures capture: the global object is
|
|
641
666
|
// only what they push.
|
|
642
667
|
for (const [d, factory, id, , params] of script.desc.traits.methods) {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
d,
|
|
647
|
-
withId(factory(this.empty, null), id),
|
|
648
|
-
factory,
|
|
649
|
-
params,
|
|
650
|
-
);
|
|
668
|
+
const method = withId(factory(this.empty, this.scriptSuper), id);
|
|
669
|
+
this.keepStatic(factory, method);
|
|
670
|
+
installMethod(this, traits.methodHome(3), d, method, factory, params);
|
|
651
671
|
}
|
|
652
672
|
|
|
653
673
|
// Caches keep the methods.
|
|
@@ -677,7 +697,7 @@ export class Runtime {
|
|
|
677
697
|
if (script.state === 0 || (retry && script.state === 3)) {
|
|
678
698
|
script.state = 1;
|
|
679
699
|
try {
|
|
680
|
-
script.desc.init(this.empty,
|
|
700
|
+
script.desc.init(this.empty, this.scriptSuper).call(g);
|
|
681
701
|
} catch (e) {
|
|
682
702
|
script.state = 3;
|
|
683
703
|
throw e;
|
|
@@ -1095,7 +1115,21 @@ export class Runtime {
|
|
|
1095
1115
|
this.arrayConversion.noteArrayClass(cls);
|
|
1096
1116
|
}
|
|
1097
1117
|
|
|
1118
|
+
/**
|
|
1119
|
+
* A class's prototype, whose methods compiled code calls on a primitive:
|
|
1120
|
+
* at every such call, so a String's, a Number's and a Boolean's are read
|
|
1121
|
+
* from their traits, kept once known, without the lookup by name.
|
|
1122
|
+
*/
|
|
1098
1123
|
prototypeOf(ref: TypeRef): AsObject {
|
|
1124
|
+
switch (ref) {
|
|
1125
|
+
case "String":
|
|
1126
|
+
return (this.stringTraits ?? this.builtinTraits("String")).proto;
|
|
1127
|
+
case "Number":
|
|
1128
|
+
return (this.numberTraits ?? this.builtinTraits("Number")).proto;
|
|
1129
|
+
case "Boolean":
|
|
1130
|
+
return (this.booleanTraits ?? this.builtinTraits("Boolean")).proto;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1099
1133
|
return this.classOf(ref).$it.proto;
|
|
1100
1134
|
}
|
|
1101
1135
|
|
|
@@ -1197,7 +1231,7 @@ export class Runtime {
|
|
|
1197
1231
|
"ReferenceError",
|
|
1198
1232
|
name === null && nsset ? 1081 : 1069,
|
|
1199
1233
|
mn.name ?? "*",
|
|
1200
|
-
traits.
|
|
1234
|
+
traits.errorName,
|
|
1201
1235
|
);
|
|
1202
1236
|
}
|
|
1203
1237
|
|
|
@@ -1273,6 +1307,31 @@ export class Runtime {
|
|
|
1273
1307
|
this.setProperty(o, this.indexName(mn, i), v);
|
|
1274
1308
|
}
|
|
1275
1309
|
|
|
1310
|
+
/**
|
|
1311
|
+
* obj[k] by a runtime name with no public namespace, or an attribute's,
|
|
1312
|
+
* in a script's or a class's initializer, which avmplus interprets: its
|
|
1313
|
+
* getproperty reads an int key of at least 0 off an object by
|
|
1314
|
+
* getUintProperty, whatever namespaces the name has, where its JIT asks
|
|
1315
|
+
* for a public one (getIndexed). Any other key makes a name.
|
|
1316
|
+
*/
|
|
1317
|
+
getInterpreted(o: Value, mn: Multiname, k: Value): Value {
|
|
1318
|
+
if (uintAtom(k) && isScriptObject(o)) {
|
|
1319
|
+
return this.getIndexed(o, ELEMENT_NAME, k);
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
return this.getProperty(o, this.runtimeName(mn, k));
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
/** obj[k] = v as getInterpreted reads it, as avmplus' interpreter's setproperty. */
|
|
1326
|
+
setInterpreted(o: Value, mn: Multiname, k: Value, v: Value): void {
|
|
1327
|
+
if (uintAtom(k) && isScriptObject(o)) {
|
|
1328
|
+
this.setIndexed(o, ELEMENT_NAME, k, v);
|
|
1329
|
+
return;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
this.setProperty(o, this.runtimeName(mn, k), v);
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1276
1335
|
/**
|
|
1277
1336
|
* obj[k] for a key whose type the compiler does not know, by a name with
|
|
1278
1337
|
* no namespace from the stack, as avmplus' getprop_index and
|
|
@@ -1578,10 +1637,10 @@ export class Runtime {
|
|
|
1578
1637
|
return o[slot];
|
|
1579
1638
|
}
|
|
1580
1639
|
|
|
1581
|
-
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.
|
|
1640
|
+
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.errorName);
|
|
1582
1641
|
}
|
|
1583
1642
|
default:
|
|
1584
|
-
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.
|
|
1643
|
+
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.errorName);
|
|
1585
1644
|
}
|
|
1586
1645
|
}
|
|
1587
1646
|
|
|
@@ -1683,7 +1742,7 @@ export class Runtime {
|
|
|
1683
1742
|
switch (b & 7) {
|
|
1684
1743
|
case BIND_Const:
|
|
1685
1744
|
if (!init) {
|
|
1686
|
-
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.
|
|
1745
|
+
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.errorName);
|
|
1687
1746
|
}
|
|
1688
1747
|
o[slotKey(id)] = this.coerce(v, traits.slotType(id));
|
|
1689
1748
|
return;
|
|
@@ -1695,9 +1754,9 @@ export class Runtime {
|
|
|
1695
1754
|
(traits.proto[untypedSetKey(id + 1)] ?? traits.proto[methodKey(id + 1)]).call(o, v);
|
|
1696
1755
|
return;
|
|
1697
1756
|
case BIND_Method:
|
|
1698
|
-
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.
|
|
1757
|
+
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.errorName);
|
|
1699
1758
|
default:
|
|
1700
|
-
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.
|
|
1759
|
+
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.errorName);
|
|
1701
1760
|
}
|
|
1702
1761
|
}
|
|
1703
1762
|
|
|
@@ -1722,7 +1781,7 @@ export class Runtime {
|
|
|
1722
1781
|
}
|
|
1723
1782
|
}
|
|
1724
1783
|
|
|
1725
|
-
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.
|
|
1784
|
+
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.errorName);
|
|
1726
1785
|
}
|
|
1727
1786
|
|
|
1728
1787
|
initProperty(o: Value, mn: Multiname, v: Value): void {
|
|
@@ -1741,7 +1800,7 @@ export class Runtime {
|
|
|
1741
1800
|
|
|
1742
1801
|
// A primitive's property cannot be deleted, as MethodEnv's delproperty has it.
|
|
1743
1802
|
if (typeof o !== "object" || o instanceof Namespace) {
|
|
1744
|
-
throw this.error("ReferenceError", 1120, mn.name ?? "*", this.traitsOf(o).
|
|
1803
|
+
throw this.error("ReferenceError", 1120, mn.name ?? "*", this.traitsOf(o).errorName);
|
|
1745
1804
|
}
|
|
1746
1805
|
|
|
1747
1806
|
// E4X 11.3.1: delete x[list] is a TypeError, as in delete x.a.(b == 1).
|
|
@@ -1958,6 +2017,36 @@ export class Runtime {
|
|
|
1958
2017
|
return qname(publicNs, this.nameString(name));
|
|
1959
2018
|
}
|
|
1960
2019
|
|
|
2020
|
+
// Natives' typed reach into AS3 objects (as3-types.ts): getProperty,
|
|
2021
|
+
// setProperty and callProperty of the public name, the lookup natives
|
|
2022
|
+
// made before, with the name checked against the class's declarations
|
|
2023
|
+
// when compiled.
|
|
2024
|
+
|
|
2025
|
+
/** `o`'s public property `name`: a variable, constant or accessor its class declares. */
|
|
2026
|
+
prop<T, K extends PropertyName<T>>(o: Ref<T>, name: K): T[K] {
|
|
2027
|
+
// biome-ignore lint/style/useConst: a const is folded into a tail call (see getProperty)
|
|
2028
|
+
let r: Value;
|
|
2029
|
+
r = this.getProperty(o, this.publicName(name));
|
|
2030
|
+
return r;
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
/** Sets `o`'s public property `name`, which its class declares writable. */
|
|
2034
|
+
setProp<T, K extends WritableName<T>>(o: Ref<T>, name: K, v: T[K]): void {
|
|
2035
|
+
this.setProperty(o, this.publicName(name), v);
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2038
|
+
/** Calls `o`'s public method `name` with `args`. */
|
|
2039
|
+
callProp<T, K extends MethodName<T>>(
|
|
2040
|
+
o: Ref<T>,
|
|
2041
|
+
name: K,
|
|
2042
|
+
...args: T[K] extends (...a: infer A) => unknown ? A : never
|
|
2043
|
+
): T[K] extends (...a: never[]) => infer R ? R : never {
|
|
2044
|
+
// biome-ignore lint/style/useConst: a const is folded into a tail call (see getProperty)
|
|
2045
|
+
let r: Value;
|
|
2046
|
+
r = this.callProperty(o, this.publicName(name), ...args);
|
|
2047
|
+
return r;
|
|
2048
|
+
}
|
|
2049
|
+
|
|
1961
2050
|
/** A property name as a string, as ToString makes one. */
|
|
1962
2051
|
private nameString(name: Value): string {
|
|
1963
2052
|
return typeof name === "string" ? name : this.toString(name);
|
|
@@ -2208,8 +2297,33 @@ export class Runtime {
|
|
|
2208
2297
|
return key;
|
|
2209
2298
|
}
|
|
2210
2299
|
|
|
2211
|
-
|
|
2212
|
-
|
|
2300
|
+
/**
|
|
2301
|
+
* The first method each factory made for a class's or a script's
|
|
2302
|
+
* traits, as avmplus' AbcEnv keeps the first MethodEnv of each method
|
|
2303
|
+
* a vtable makes (VTable::makeMethodEnv): what callstatic calls.
|
|
2304
|
+
*/
|
|
2305
|
+
private readonly staticMethods = new WeakMap<Factory, Method>();
|
|
2306
|
+
|
|
2307
|
+
/** Keep `method`, made by `factory`, for callstatic, unless it made one before. */
|
|
2308
|
+
keepStatic(factory: Factory, method: Method): void {
|
|
2309
|
+
if (!this.staticMethods.has(factory)) {
|
|
2310
|
+
this.staticMethods.set(factory, method);
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
/**
|
|
2315
|
+
* callstatic: method `factory` made, called on `o` with its arguments,
|
|
2316
|
+
* which the compiler coerced. avmplus verifies a method when it first
|
|
2317
|
+
* runs and refuses one that calls a method no vtable has made yet
|
|
2318
|
+
* (1107); that is found here only once the call is reached.
|
|
2319
|
+
*/
|
|
2320
|
+
callStatic(factory: Factory, o: Value, ...args: Value[]): Value {
|
|
2321
|
+
const method = this.staticMethods.get(factory);
|
|
2322
|
+
if (method === undefined) {
|
|
2323
|
+
throw this.error("VerifyError", 1107);
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
return method.apply(o, args);
|
|
2213
2327
|
}
|
|
2214
2328
|
|
|
2215
2329
|
// The super operations, as MethodEnv's: by the base class's traits
|
|
@@ -2225,7 +2339,7 @@ export class Runtime {
|
|
|
2225
2339
|
}
|
|
2226
2340
|
|
|
2227
2341
|
if (b === 0) {
|
|
2228
|
-
throw this.error("ReferenceError", 1070, mn.name ?? "*", traits.
|
|
2342
|
+
throw this.error("ReferenceError", 1070, mn.name ?? "*", traits.errorName);
|
|
2229
2343
|
}
|
|
2230
2344
|
|
|
2231
2345
|
r = this.callValue(this.getBound(o, traits, b, mn), o, args, mn);
|
|
@@ -2236,7 +2350,7 @@ export class Runtime {
|
|
|
2236
2350
|
const traits: Traits = sup.$it;
|
|
2237
2351
|
const b = traits.find(mn);
|
|
2238
2352
|
if (b === 0) {
|
|
2239
|
-
throw this.error("ReferenceError", 1069, mn.name ?? "*", traits.
|
|
2353
|
+
throw this.error("ReferenceError", 1069, mn.name ?? "*", traits.errorName);
|
|
2240
2354
|
}
|
|
2241
2355
|
|
|
2242
2356
|
return this.getBound(o, traits, b, mn);
|
|
@@ -2255,11 +2369,11 @@ export class Runtime {
|
|
|
2255
2369
|
o[slotKey(id)] = this.coerce(v, traits.slotType(id));
|
|
2256
2370
|
return;
|
|
2257
2371
|
case BIND_Method:
|
|
2258
|
-
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.
|
|
2372
|
+
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.errorName);
|
|
2259
2373
|
case 0:
|
|
2260
|
-
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.
|
|
2374
|
+
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.errorName);
|
|
2261
2375
|
default:
|
|
2262
|
-
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.
|
|
2376
|
+
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.errorName);
|
|
2263
2377
|
}
|
|
2264
2378
|
}
|
|
2265
2379
|
|
|
@@ -2734,7 +2848,7 @@ export class Runtime {
|
|
|
2734
2848
|
return v;
|
|
2735
2849
|
}
|
|
2736
2850
|
|
|
2737
|
-
throw this.error("TypeError", 1034, this.describe(v), traits.
|
|
2851
|
+
throw this.error("TypeError", 1034, this.describe(v), traits.errorName);
|
|
2738
2852
|
}
|
|
2739
2853
|
}
|
|
2740
2854
|
}
|
|
@@ -2759,7 +2873,7 @@ export class Runtime {
|
|
|
2759
2873
|
return v;
|
|
2760
2874
|
}
|
|
2761
2875
|
|
|
2762
|
-
throw this.error("TypeError", 1034, this.describe(v), traits.
|
|
2876
|
+
throw this.error("TypeError", 1034, this.describe(v), traits.errorName);
|
|
2763
2877
|
}
|
|
2764
2878
|
|
|
2765
2879
|
coerceString(v: Value): string | null {
|
|
@@ -3000,7 +3114,7 @@ export class Runtime {
|
|
|
3000
3114
|
}
|
|
3001
3115
|
}
|
|
3002
3116
|
|
|
3003
|
-
throw this.error("TypeError", 1050, o.$traits.
|
|
3117
|
+
throw this.error("TypeError", 1050, o.$traits.errorName);
|
|
3004
3118
|
}
|
|
3005
3119
|
|
|
3006
3120
|
add(a: Value, b: Value): Value {
|
package/src/avm2/traits.ts
CHANGED
|
@@ -187,6 +187,26 @@ export class Traits {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Its name as Flash's debugger player writes it in an error message
|
|
192
|
+
* (AvmCore::toErrorString): the package and the name joined by a dot,
|
|
193
|
+
* "flash.text.TextField"; a class object's as "class " and its class's.
|
|
194
|
+
*/
|
|
195
|
+
get errorName(): string {
|
|
196
|
+
let name = this.name;
|
|
197
|
+
const statics = this.base?.name === "Class" && name.endsWith("$");
|
|
198
|
+
if (statics) {
|
|
199
|
+
name = name.slice(0, -1);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const colons = name.lastIndexOf("::");
|
|
203
|
+
if (colons >= 0) {
|
|
204
|
+
name = `${name.slice(0, colons)}.${name.slice(colons + 2)}`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return statics ? `class ${name}` : name;
|
|
208
|
+
}
|
|
209
|
+
|
|
190
210
|
/**
|
|
191
211
|
* The object a method and its entries, `count` properties, go into:
|
|
192
212
|
* the prototype, till it holds HOME_PROPERTIES, then an object chained
|