-
-
Notifications
You must be signed in to change notification settings - Fork 828
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
AVM2 verifier #14631
AVM2 verifier #14631
Conversation
86c94d3
to
bf58273
Compare
|
||
let mut previous_op = None; | ||
for (i, op) in code.iter_mut().enumerate() { | ||
if let Some(previous_op_some) = previous_op { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we unnest this a bit? (And definitely rename previous_op_some
)
e.g.
let previous_op = if let Some(previous_op) = previous_op {
previous_op
} else {
previous_op = Some(op.clone());
}
In theory we could even do something like
previous_op = code.first();
for (...) in code.iter_mut().enumerate().skip(1) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't do let Some(previous_op) = previous_op
because the optimizer needs to set the Option
value of previous_op
. I'll try unnesting it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried unnesting it but I realized that there are likely going to be optimizations that we can do that would work despite previous_op
being None
, and/or those that would work even when the next op is on a jump target.
| Op::Not | ||
| Op::IsType { .. } | ||
| Op::IsTypeLate => { | ||
previous_op = Some(op.clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could write this as previous_op = mem::replace(op, Op::Nop)
, but I am not sure if that is really worth it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this current implementation is more readable.
6c6cd46
to
f01c5a7
Compare
c3b47f3
to
f552d34
Compare
f7702cd
to
e187b1b
Compare
a5509f4
to
99d9d44
Compare
false | ||
} | ||
|
||
fn pool_int<'gc>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we move these to script.rs
? It already has a bunch of similar functions, so it'd be more consistent (and decrease verify.rs size a bit too).
Also, any chance this could be unified with abc_int()
(and friends)? As they are pretty much duplicates, sans 0
treatment. (this'd also probably make function with invalid default values throw a correct VerifyError "for free"). Can be left for a follow-up though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to leave this for a follow-up to also fix more issues with namespace and string pooling
99d9d44
to
73fdce3
Compare
…s since those are equivalent to the corresponding CoerceX opcodes
…ention them but don't actually use them
…line `CoerceA` and `Nop`
…ix `optimize` panicking when out-of-bounds local registers are mentioned
…ing recursively This fixes a stack overflow on one test.
…` pointing to the same cpool entry
…::ops_can_throw_error` This requires a minor change to `Activation::op_lookup_switch`
… `NewArray`, and `NewFunction`
e91ef59
to
190669d
Compare
This is #14563 but with state merging removed, since I couldn't figure it out. It also includes some basic optimizations, and it keeps verification of local registers in (since that's not dependent on the control flow).
TODO:
Something in try..catch blocks is broken (I keep losing working reproductions, but FP is throwing verify errors where Ruffle is not)Not relevant anymoreAlso only verify exception target if there are any potentially error-throwing opcodes present in the from..toFixedAll error-throwing opcodes in the from..to should act as a potential jump to the exception target (just likeFixed, like aboveiftrue
,iffalse
, etc)- example: verify.zipMore brokennessNot relevant anymoremanytwo testsparsed_code
on the method itself rather than inAbcMethodBody
AbcMethodBody
seems unnecessary, and is mostly leftover from Adrian's original workThe optimization framework that this PR implements should work well with #7920.
Supersedes #14563.
Future optimizations:
Nop
opcodes in code and modify jump offsetssetproperty
/initproperty
andcallproperty
/callpropvoid