-
-
Notifications
You must be signed in to change notification settings - Fork 881
Allow supercalled methods to access properties of this correctly #499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks for the work and tests! I don't think we need the
You can also try the Another example:
|
…ions can still initialize the object they are a part of.
…e object from which a particular function was retrieved from. A base prototype is only applicable in cases where a method is being called as a property on an object. Bare function calls, `apply`/`call` calls, and so on do not generate a base prototype. We also add a convenience method, `call_method`, to all objects. This method automatically calculates the correct base prototype for a method call on an object, which is the only operation that should generate base prototypes.
…g copies of itself as `this`. This allows supercalled functions to properly read and mutate the object they were called on.
…uper-methods, super-getters, and super-setters.
…stead of itself as `this`.
This is accomplished via two new `TObject` methods: `has_own_virtual` and `call_setter`. If an object does not contain it's own version of a property, it will first crawl the prototype chain to see if there is an overwritable virtual. If so, it will invoke that prototype's setter. A bit of borrow finangling was required to do this; `super` now no longer caches it's proto and constr values and instead dynamically constructs them. This also means it can't be downcasted to `Executable` anymore. With this commit, virtual setters and super-setters now work correctly.
…e source compiled to SWF version 6.
…d by mx (currently broken)
I... really wish I had know about |
… property called `__constructor__` to store the constructor. A previous version of this PR (whose history has been scrubbed, but go check 918d88a if you're curious) implemented a new `TObject` property which basically every line of code that dealt with object construction had to populate. It was terrible.
I've updated the PR to use This passes all tests and clippy lints as far as I'm aware, but I may push again if it fails on CI or the newest Rust compiler update (currently installing) adds more failing lints. |
Thanks! |
Fixes #496. Also, properly implements AS2 virtual setters, which were broken but went unnoticed. All four types of supercalls (super-constructors, super-methods, super-getters, and super-setters) now work as expected.
Why it broke
The underlying
super
mechanism for AVM1 involves a special VM-provided object that pulls properties from the prototype that the currently-executing method was pulled from. This is difficult to correctly implement because it requires method calls to be treated differently from invoking a function with a particular value ofthis
. The previous approach was to implementsuper
as a proxy tothis
, but with one fewer prototype. This almost worked and was the approach that survived up until I decided to pare downsuper
to the few operations that it actually supports. When you super-called a method, it would get the previous method'ssuper
as it'sthis
. Makingsuper
more accurate to how Flash worked broke the ability for super-called methods to access their object properties.How it got fixed
In AVM2,
super
is a set of opcodes, rather than an object. Because of this, I was more-or-less forced into avoiding the above hack and instead implementingsuper
correctly. This PR constitutes a backport of PR #404'ssuper
handling to AVM1. When a method is called, the prototype that generated the method (calledbase_proto
) is provided tocall
. If a method requestssuper
, then aSuperObject
is generated holding thebase_proto
. Furthermore, becausesuper.method
needs to bind the originalthis
, a new trait method calledcall_method
is provided to invoke a method on an object with correctthis
andsuper
handling. All code, including builtin functions, that needs to invoke object methods should usecall_method
rather than resolving the property and calling it itself.