@swf2es/runtime 0.1.16 → 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/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 +39 -1
- package/dist/avm2/runtime.d.ts.map +1 -1
- package/dist/avm2/runtime.js +106 -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 +127 -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;
|
|
@@ -1197,7 +1217,7 @@ export class Runtime {
|
|
|
1197
1217
|
"ReferenceError",
|
|
1198
1218
|
name === null && nsset ? 1081 : 1069,
|
|
1199
1219
|
mn.name ?? "*",
|
|
1200
|
-
traits.
|
|
1220
|
+
traits.errorName,
|
|
1201
1221
|
);
|
|
1202
1222
|
}
|
|
1203
1223
|
|
|
@@ -1273,6 +1293,31 @@ export class Runtime {
|
|
|
1273
1293
|
this.setProperty(o, this.indexName(mn, i), v);
|
|
1274
1294
|
}
|
|
1275
1295
|
|
|
1296
|
+
/**
|
|
1297
|
+
* obj[k] by a runtime name with no public namespace, or an attribute's,
|
|
1298
|
+
* in a script's or a class's initializer, which avmplus interprets: its
|
|
1299
|
+
* getproperty reads an int key of at least 0 off an object by
|
|
1300
|
+
* getUintProperty, whatever namespaces the name has, where its JIT asks
|
|
1301
|
+
* for a public one (getIndexed). Any other key makes a name.
|
|
1302
|
+
*/
|
|
1303
|
+
getInterpreted(o: Value, mn: Multiname, k: Value): Value {
|
|
1304
|
+
if (uintAtom(k) && isScriptObject(o)) {
|
|
1305
|
+
return this.getIndexed(o, ELEMENT_NAME, k);
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
return this.getProperty(o, this.runtimeName(mn, k));
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
/** obj[k] = v as getInterpreted reads it, as avmplus' interpreter's setproperty. */
|
|
1312
|
+
setInterpreted(o: Value, mn: Multiname, k: Value, v: Value): void {
|
|
1313
|
+
if (uintAtom(k) && isScriptObject(o)) {
|
|
1314
|
+
this.setIndexed(o, ELEMENT_NAME, k, v);
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
this.setProperty(o, this.runtimeName(mn, k), v);
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1276
1321
|
/**
|
|
1277
1322
|
* obj[k] for a key whose type the compiler does not know, by a name with
|
|
1278
1323
|
* no namespace from the stack, as avmplus' getprop_index and
|
|
@@ -1578,10 +1623,10 @@ export class Runtime {
|
|
|
1578
1623
|
return o[slot];
|
|
1579
1624
|
}
|
|
1580
1625
|
|
|
1581
|
-
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.
|
|
1626
|
+
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.errorName);
|
|
1582
1627
|
}
|
|
1583
1628
|
default:
|
|
1584
|
-
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.
|
|
1629
|
+
throw this.error("ReferenceError", 1077, mn.name ?? "*", traits.errorName);
|
|
1585
1630
|
}
|
|
1586
1631
|
}
|
|
1587
1632
|
|
|
@@ -1683,7 +1728,7 @@ export class Runtime {
|
|
|
1683
1728
|
switch (b & 7) {
|
|
1684
1729
|
case BIND_Const:
|
|
1685
1730
|
if (!init) {
|
|
1686
|
-
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.
|
|
1731
|
+
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.errorName);
|
|
1687
1732
|
}
|
|
1688
1733
|
o[slotKey(id)] = this.coerce(v, traits.slotType(id));
|
|
1689
1734
|
return;
|
|
@@ -1695,9 +1740,9 @@ export class Runtime {
|
|
|
1695
1740
|
(traits.proto[untypedSetKey(id + 1)] ?? traits.proto[methodKey(id + 1)]).call(o, v);
|
|
1696
1741
|
return;
|
|
1697
1742
|
case BIND_Method:
|
|
1698
|
-
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.
|
|
1743
|
+
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.errorName);
|
|
1699
1744
|
default:
|
|
1700
|
-
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.
|
|
1745
|
+
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.errorName);
|
|
1701
1746
|
}
|
|
1702
1747
|
}
|
|
1703
1748
|
|
|
@@ -1722,7 +1767,7 @@ export class Runtime {
|
|
|
1722
1767
|
}
|
|
1723
1768
|
}
|
|
1724
1769
|
|
|
1725
|
-
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.
|
|
1770
|
+
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.errorName);
|
|
1726
1771
|
}
|
|
1727
1772
|
|
|
1728
1773
|
initProperty(o: Value, mn: Multiname, v: Value): void {
|
|
@@ -1741,7 +1786,7 @@ export class Runtime {
|
|
|
1741
1786
|
|
|
1742
1787
|
// A primitive's property cannot be deleted, as MethodEnv's delproperty has it.
|
|
1743
1788
|
if (typeof o !== "object" || o instanceof Namespace) {
|
|
1744
|
-
throw this.error("ReferenceError", 1120, mn.name ?? "*", this.traitsOf(o).
|
|
1789
|
+
throw this.error("ReferenceError", 1120, mn.name ?? "*", this.traitsOf(o).errorName);
|
|
1745
1790
|
}
|
|
1746
1791
|
|
|
1747
1792
|
// E4X 11.3.1: delete x[list] is a TypeError, as in delete x.a.(b == 1).
|
|
@@ -1958,6 +2003,36 @@ export class Runtime {
|
|
|
1958
2003
|
return qname(publicNs, this.nameString(name));
|
|
1959
2004
|
}
|
|
1960
2005
|
|
|
2006
|
+
// Natives' typed reach into AS3 objects (as3-types.ts): getProperty,
|
|
2007
|
+
// setProperty and callProperty of the public name, the lookup natives
|
|
2008
|
+
// made before, with the name checked against the class's declarations
|
|
2009
|
+
// when compiled.
|
|
2010
|
+
|
|
2011
|
+
/** `o`'s public property `name`: a variable, constant or accessor its class declares. */
|
|
2012
|
+
prop<T, K extends PropertyName<T>>(o: Ref<T>, name: K): T[K] {
|
|
2013
|
+
// biome-ignore lint/style/useConst: a const is folded into a tail call (see getProperty)
|
|
2014
|
+
let r: Value;
|
|
2015
|
+
r = this.getProperty(o, this.publicName(name));
|
|
2016
|
+
return r;
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
/** Sets `o`'s public property `name`, which its class declares writable. */
|
|
2020
|
+
setProp<T, K extends WritableName<T>>(o: Ref<T>, name: K, v: T[K]): void {
|
|
2021
|
+
this.setProperty(o, this.publicName(name), v);
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
/** Calls `o`'s public method `name` with `args`. */
|
|
2025
|
+
callProp<T, K extends MethodName<T>>(
|
|
2026
|
+
o: Ref<T>,
|
|
2027
|
+
name: K,
|
|
2028
|
+
...args: T[K] extends (...a: infer A) => unknown ? A : never
|
|
2029
|
+
): T[K] extends (...a: never[]) => infer R ? R : never {
|
|
2030
|
+
// biome-ignore lint/style/useConst: a const is folded into a tail call (see getProperty)
|
|
2031
|
+
let r: Value;
|
|
2032
|
+
r = this.callProperty(o, this.publicName(name), ...args);
|
|
2033
|
+
return r;
|
|
2034
|
+
}
|
|
2035
|
+
|
|
1961
2036
|
/** A property name as a string, as ToString makes one. */
|
|
1962
2037
|
private nameString(name: Value): string {
|
|
1963
2038
|
return typeof name === "string" ? name : this.toString(name);
|
|
@@ -2208,8 +2283,33 @@ export class Runtime {
|
|
|
2208
2283
|
return key;
|
|
2209
2284
|
}
|
|
2210
2285
|
|
|
2211
|
-
|
|
2212
|
-
|
|
2286
|
+
/**
|
|
2287
|
+
* The first method each factory made for a class's or a script's
|
|
2288
|
+
* traits, as avmplus' AbcEnv keeps the first MethodEnv of each method
|
|
2289
|
+
* a vtable makes (VTable::makeMethodEnv): what callstatic calls.
|
|
2290
|
+
*/
|
|
2291
|
+
private readonly staticMethods = new WeakMap<Factory, Method>();
|
|
2292
|
+
|
|
2293
|
+
/** Keep `method`, made by `factory`, for callstatic, unless it made one before. */
|
|
2294
|
+
keepStatic(factory: Factory, method: Method): void {
|
|
2295
|
+
if (!this.staticMethods.has(factory)) {
|
|
2296
|
+
this.staticMethods.set(factory, method);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
/**
|
|
2301
|
+
* callstatic: method `factory` made, called on `o` with its arguments,
|
|
2302
|
+
* which the compiler coerced. avmplus verifies a method when it first
|
|
2303
|
+
* runs and refuses one that calls a method no vtable has made yet
|
|
2304
|
+
* (1107); that is found here only once the call is reached.
|
|
2305
|
+
*/
|
|
2306
|
+
callStatic(factory: Factory, o: Value, ...args: Value[]): Value {
|
|
2307
|
+
const method = this.staticMethods.get(factory);
|
|
2308
|
+
if (method === undefined) {
|
|
2309
|
+
throw this.error("VerifyError", 1107);
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2312
|
+
return method.apply(o, args);
|
|
2213
2313
|
}
|
|
2214
2314
|
|
|
2215
2315
|
// The super operations, as MethodEnv's: by the base class's traits
|
|
@@ -2225,7 +2325,7 @@ export class Runtime {
|
|
|
2225
2325
|
}
|
|
2226
2326
|
|
|
2227
2327
|
if (b === 0) {
|
|
2228
|
-
throw this.error("ReferenceError", 1070, mn.name ?? "*", traits.
|
|
2328
|
+
throw this.error("ReferenceError", 1070, mn.name ?? "*", traits.errorName);
|
|
2229
2329
|
}
|
|
2230
2330
|
|
|
2231
2331
|
r = this.callValue(this.getBound(o, traits, b, mn), o, args, mn);
|
|
@@ -2236,7 +2336,7 @@ export class Runtime {
|
|
|
2236
2336
|
const traits: Traits = sup.$it;
|
|
2237
2337
|
const b = traits.find(mn);
|
|
2238
2338
|
if (b === 0) {
|
|
2239
|
-
throw this.error("ReferenceError", 1069, mn.name ?? "*", traits.
|
|
2339
|
+
throw this.error("ReferenceError", 1069, mn.name ?? "*", traits.errorName);
|
|
2240
2340
|
}
|
|
2241
2341
|
|
|
2242
2342
|
return this.getBound(o, traits, b, mn);
|
|
@@ -2255,11 +2355,11 @@ export class Runtime {
|
|
|
2255
2355
|
o[slotKey(id)] = this.coerce(v, traits.slotType(id));
|
|
2256
2356
|
return;
|
|
2257
2357
|
case BIND_Method:
|
|
2258
|
-
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.
|
|
2358
|
+
throw this.error("ReferenceError", 1037, mn.name ?? "*", traits.errorName);
|
|
2259
2359
|
case 0:
|
|
2260
|
-
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.
|
|
2360
|
+
throw this.error("ReferenceError", 1056, mn.name ?? "*", traits.errorName);
|
|
2261
2361
|
default:
|
|
2262
|
-
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.
|
|
2362
|
+
throw this.error("ReferenceError", 1074, mn.name ?? "*", traits.errorName);
|
|
2263
2363
|
}
|
|
2264
2364
|
}
|
|
2265
2365
|
|
|
@@ -2734,7 +2834,7 @@ export class Runtime {
|
|
|
2734
2834
|
return v;
|
|
2735
2835
|
}
|
|
2736
2836
|
|
|
2737
|
-
throw this.error("TypeError", 1034, this.describe(v), traits.
|
|
2837
|
+
throw this.error("TypeError", 1034, this.describe(v), traits.errorName);
|
|
2738
2838
|
}
|
|
2739
2839
|
}
|
|
2740
2840
|
}
|
|
@@ -2759,7 +2859,7 @@ export class Runtime {
|
|
|
2759
2859
|
return v;
|
|
2760
2860
|
}
|
|
2761
2861
|
|
|
2762
|
-
throw this.error("TypeError", 1034, this.describe(v), traits.
|
|
2862
|
+
throw this.error("TypeError", 1034, this.describe(v), traits.errorName);
|
|
2763
2863
|
}
|
|
2764
2864
|
|
|
2765
2865
|
coerceString(v: Value): string | null {
|
|
@@ -3000,7 +3100,7 @@ export class Runtime {
|
|
|
3000
3100
|
}
|
|
3001
3101
|
}
|
|
3002
3102
|
|
|
3003
|
-
throw this.error("TypeError", 1050, o.$traits.
|
|
3103
|
+
throw this.error("TypeError", 1050, o.$traits.errorName);
|
|
3004
3104
|
}
|
|
3005
3105
|
|
|
3006
3106
|
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
|