|
| 1 | +// Compile with: |
| 2 | +// mtasc -main -version 8 Test.as -swf shim.swf -keep -out test.swf |
| 3 | +class Test { |
| 4 | + |
| 5 | + // shim.swf provides this function, which wraps the `CastOp` AVM1 action. |
| 6 | + // arguments: (object, constructor) |
| 7 | + // It is normally available through `catch(e: Class)`, but direct access |
| 8 | + // makes for simpler test code, and allows inspecting the actual return value. |
| 9 | + static var opcode__cast = _root.opcode__cast; |
| 10 | + |
| 11 | + static function main(current) { |
| 12 | + _global.String = NoisyString; |
| 13 | + |
| 14 | + trace('// obj: "left", class: "right"'); |
| 15 | + check("left", "right"); |
| 16 | + trace('// obj: "left", class: Object'); |
| 17 | + check("left", Object); |
| 18 | + trace('// obj: {}, class: "right"'); |
| 19 | + check({}, "right"); |
| 20 | + trace(''); |
| 21 | + |
| 22 | + trace('// obj: {}, class: { prototype: Object.prototype }'); |
| 23 | + check({}, { prototype: Object.prototype }); |
| 24 | + |
| 25 | + trace('// obj: { __proto__: "left" }, class: { prototype: "right" }'); |
| 26 | + check({ __proto__: "left" }, { prototype: "right" }); |
| 27 | + |
| 28 | + trace('// obj: { __proto__: "proto" }, class: { prototype: "proto" }'); |
| 29 | + check({ __proto__: "proto" }, { prototype: "proto" }); |
| 30 | + |
| 31 | + trace('// obj: { __proto__: null }, class: { prototype: null }'); |
| 32 | + check({ __proto__: null }, { prototype: null }); |
| 33 | + |
| 34 | + // Prototype properties don't work... |
| 35 | + var fakeClass = {}; |
| 36 | + fakeClass.addProperty("prototype", function() { |
| 37 | + trace("prototype property called!"); |
| 38 | + return "property proto"; |
| 39 | + }, null); |
| 40 | + trace('// obj: {}, class: { get prototype(): ... }'); |
| 41 | + trace('.prototype is: ' + fakeClass.prototype); |
| 42 | + check({}, fakeClass); |
| 43 | + |
| 44 | + // ...and neither do 'indirect' prototypes... |
| 45 | + fakeClass = { __proto__: { prototype: {}}}; |
| 46 | + trace('// obj: { __proto__: X }, class: { __proto__: { prototype: X }}'); |
| 47 | + check({ __proto__: fakeClass.prototype }, fakeClass); |
| 48 | + |
| 49 | + // ...nor prototypes behind 'super'. |
| 50 | + var FakeClassSuper = function() { this.zuper = super; }; |
| 51 | + FakeClassSuper.prototype = { __proto__: { prototype: "super proto" }}; |
| 52 | + fakeClass = (new FakeClassSuper()).zuper; |
| 53 | + trace('// obj: {}, class: super { prototype: ... }'); |
| 54 | + trace('.prototype is: ' + fakeClass.prototype); |
| 55 | + check({}, fakeClass); |
| 56 | + |
| 57 | + // SWF version flags are ignored. |
| 58 | + fakeClass = { prototype: "SWFv9 proto" }; |
| 59 | + _global.ASSetPropFlags(fakeClass, "prototype", 0x2000 /* version 9 */); |
| 60 | + trace('// obj: {}, class: { prototype(SWFv9): ... }'); |
| 61 | + trace('.prototype is: ' + fakeClass.prototype); |
| 62 | + check({}, fakeClass); |
| 63 | + |
| 64 | + trace(''); |
| 65 | + |
| 66 | + var movieclip = current.createEmptyMovieClip("mc", 1); |
| 67 | + movieclip.prototype = Object.prototype; |
| 68 | + testsForMovieClip(movieclip); |
| 69 | + trace('// kill movieclip'); |
| 70 | + movieclip.removeMovieClip(); |
| 71 | + testsForMovieClip(movieclip); |
| 72 | + |
| 73 | + fscommand('quit'); |
| 74 | + } |
| 75 | + |
| 76 | + static function testsForMovieClip(movieclip) { |
| 77 | + trace('// obj: movieclip, class: "right"'); |
| 78 | + check(movieclip, "right"); |
| 79 | + trace('// obj: movieclip, class: Object'); |
| 80 | + check(movieclip, Object); |
| 81 | + trace('// obj: movieclip, class: { prototype: "proto" }'); |
| 82 | + check(movieclip, { prototype: "proto" }); |
| 83 | + trace('// obj: {}, class: MovieClip { prototype: Object.prototype }'); |
| 84 | + check({}, movieclip); |
| 85 | + trace('// obj: { __proto__: movieclip }, class: { prototype: movieclip }'); |
| 86 | + check({ __proto__: movieclip }, { prototype: movieclip }); |
| 87 | + } |
| 88 | + |
| 89 | + static function check(obj, klass) { |
| 90 | + trace("instanceof: " + (obj instanceof klass)); |
| 91 | + trace("typeof cast: " + typeof opcode__cast(obj, klass)); |
| 92 | + } |
| 93 | +} |
0 commit comments