Skip to content

avm2: Check prototype chain in with-scope property resolution#23511

Open
bjornwein wants to merge 2 commits intoruffle-rs:masterfrom
bjornwein:fix-with-scope-prototype-lookup
Open

avm2: Check prototype chain in with-scope property resolution#23511
bjornwein wants to merge 2 commits intoruffle-rs:masterfrom
bjornwein:fix-with-scope-prototype-lookup

Conversation

@bjornwein
Copy link
Copy Markdown

Problem

When AS3 code uses XML methods like name(), children(), etc. inside a with block (pushwith opcode), the compiler generates QName(PackageNamespace(""), "name") lookups (public namespace). However, Ruffle's search_scope_stack only checked:

  1. vtable traits — XML's vtable has name() in the AS3 namespace (http://adobe.com/AS3/2006/builtin), not the public namespace → no match
  2. own properties (for with-scopes) — XML's has_own_property checks E4X child elements → no match

This caused findpropstrict to skip the XML with-scope entirely and find the property on a parent scope instead (e.g., DisplayObject.name getter returning a string), leading to Error #1006: value is not a function when trying to call the string result.

Root Cause

In avmplus, hasMultinameProperty for with-scope resolution checks own properties, traits, and the prototype chain (delegate). Ruffle was missing the prototype chain check. This matters because XML.prototype.name (and other XML methods) are defined as public-namespace dynamic properties on the prototype in XML.as (lines 183-190), bridging the AS3→public namespace gap.

Fix

Added value_has_proto_property() to search_scope_stack that walks the prototype chain checking for dynamic properties. This is called for with-scopes after the existing own-property check, matching avmplus behavior.

Testing

Tested against a real-world Flex-based SWF (hardware appliance UI) that was completely broken by this bug — the app now loads and functions correctly past login. The Error #1006 in updateTreeExpansion() is eliminated.

Existing tests pass (cargo test --release --package ruffle_core).

@Lord-McSweeney Lord-McSweeney added A-avm2 Area: AVM2 (ActionScript 3) T-fix Type: Bug fix (in something that's supposed to work already) llm The PR contains mostly LLM-generated code labels Apr 22, 2026
@evilpie
Copy link
Copy Markdown
Collaborator

evilpie commented Apr 22, 2026

Please add a test, thank you.

In avmplus, with-scope resolution via hasMultinameProperty checks own
properties, vtable traits, AND the prototype chain (delegate). Ruffle's
search_scope_stack only checked vtable traits and own properties,
missing the prototype chain entirely.

This is particularly important for E4X (XML/XMLList) objects where
methods like name(), children(), etc. are defined on the prototype in
the public namespace, but the vtable only has them in the AS3 namespace
(http://adobe.com/AS3/2006/builtin). When compiled code uses these
methods inside a 'with' block (pushwith), the compiler generates
QName(public, "name") lookups. Without prototype chain checking,
findpropstrict falls through to the wrong scope (e.g. finding
DisplayObject.name instead of XML.prototype.name), causing Error ruffle-rs#1006.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bjornwein bjornwein force-pushed the fix-with-scope-prototype-lookup branch from ac4f802 to 3b1b695 Compare April 23, 2026 08:28
@bjornwein
Copy link
Copy Markdown
Author

Thanks for looking into it. I apologize for dropping this LLM-generated PR on you.

I can confirm that the change solves a real-world problem for me. Unfortunately I don't have the knowledge to evaluate whether this is the best way to solve the specific issue.
I hope that your review will be able to spot any obvious significant performance costs or regression risks.

I (or mostly copilot) have updated the PR with a minimal-ish regression test. The test fails with error code #1065 without the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-avm2 Area: AVM2 (ActionScript 3) llm The PR contains mostly LLM-generated code T-fix Type: Bug fix (in something that's supposed to work already)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants