Skip to content
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

avm1 super doesn't correctly resolve this properties #496

Closed
Dinnerbone opened this issue Apr 11, 2020 · 1 comment · Fixed by #499
Closed

avm1 super doesn't correctly resolve this properties #496

Dinnerbone opened this issue Apr 11, 2020 · 1 comment · Fixed by #499
Labels
A-avm1 Area: AVM1 (ActionScript 1 & 2)

Comments

@Dinnerbone
Copy link
Contributor

Well that's a difficult bug to summarize.

In a method on a superclass, this should look at the current object top-down when resolving properties, and not just from the current point in the prototype chain.

Test case:

class Base {
	function Base() {
		trace("// Base");
		trace(this["test"]);
	}
}
class Extended extends Base {
	var test = "Extended";
	function Extended() {
		super();
		trace("// Extended");
		trace(this["test"]);
	}
}
class ExtendedFurther extends Extended {
	var test = "ExtendedFurther";
	function ExtendedFurther() {
		super();
		trace("// ExtendedFurther");
		trace(this["test"]);
	}
}
new ExtendedFurther();

Expected output:

// Base
ExtendedFurther
// Extended
ExtendedFurther
// ExtendedFurther
ExtendedFurther

In ruffle:

// Base
undefined
// Extended
Extended
// ExtendedFurther
ExtendedFurther
@Dinnerbone Dinnerbone changed the title avm1 super doesn't correctly resolve this properties avm1 super doesn't correctly resolve this properties Apr 11, 2020
@kmeisthax
Copy link
Member

I know how this happened. The underlying problem is how we handle super calls: super needs to remember how many levels deep we are in a call chain. The current AVM1 super implementation achieves this by maintaining a reference to the current super-prototype and super-constructor to call. However, preserving this across call boundaries is difficult. To get around having to extend call, I instead just passed super as this to the called function. This worked up until I started testing what super actually responded to in Flash Player. It actually does very little. For accuracy's sake, I reduced what super could do, which ultimately introduced this bug.

In my AVM2 proposal (PR #404), because super is NOT an AVM2 object, I couldn't store information in it. Instead, each call calculates a base_proto which is stored in the activation object, and the various super-related opcodes reference the activation's base_proto. I will attempt to backport this approach to AVM1 (where it actually makes more sense). This will also mean call and everything surrounding it will need to take a base_proto so that super and CallMethod can properly cooperate rather than the hacky AVM1 method of proxying stuff from super to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-avm1 Area: AVM1 (ActionScript 1 & 2)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants