-
-
Notifications
You must be signed in to change notification settings - Fork 925
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
Move arity-checking into variable-arity method bodies #7751
Conversation
These paths are automatically arity-checked but only along the DynamicMethod.call path. This leaves direct Java calls and indy binding without arity checking. Given the impossibility of automatically arity-checking the direct call paths, it seems best to always arity-check inside variable-arity native methods. We may want to audit all such places and remove the automatic arity- checking happening in DynamicMethod.call(..., IRbuyObject[]) so we are always checking at the point of use, where the stack trace will reflect the method name, and without double-checking in both generated wrappers and in the method itself.
21613ba
to
c782f00
Compare
In order to ensure that arity checks always happen along variable- arity paths, it makes sense for us to move the check into the method bodies rather than relying on the generated wrapper or the caller to do the check. This has several advantages: * Direct calls from Java will now be checked. * Direct calls from invokedynamic call sites will be checked. * The generated invokers will have less data and do less arity- checking. Splitting methods by arity will still enable direct calls to bypass the arity check. The pattern I used here, which we may want to adopt as a recommended pattern, is as follows: * If the method accesses the contents of the array direct or * If the method passes the array on to other code that accesses its contents directly without a check then * A manual arity-check should be performed before any other operations.
c782f00
to
5565751
Compare
As part of jruby/jruby#7751 we are recommending that all extension code manually check the arity of incoming arguments to variable- arity methods, as in CRuby. This ensures that all call paths will be checked, including direct paths from Java or invokedynamic, and avoids array indexing errors in these situations.
This will be fixed once ruby/stringio#48 is merged and released.
As part of jruby/jruby#7751 we are recommending that all extension code manually check the arity of incoming arguments to variable- arity methods, as in CRuby. This ensures that all call paths will be checked, including direct paths from Java or invokedynamic, and avoids array indexing errors in these situations.
This PR introduced the behavior change in 9.4.3.0 observed in #7851. Given that this breaks 3rd party extensions that work correctly on 9.4.2.0 and below, I recommend rolling this back in 9.4.3.1 so that JRuby users using these extensions are not negatively impacted by an upgrade from an older version of JRuby. If there is a long term need for this breaking change, it should be rescheduled and introduced in a major version bump. |
These were all moved to manual arity-checking in jruby#7751, but that led to breakage when third-party extensions had varargs paths that did not check arity manually (see jruby#7851). Instead we restore the default to auto arity-check with this flag provided for opting out (jruby#7680).
These were all moved to manual arity-checking in jruby#7751, but that led to breakage when third-party extensions had varargs paths that did not check arity manually (see jruby#7851). Instead we restore the default to auto arity-check with this flag provided for opting out (jruby#7680).
During testing of indy-based compilation, it became obvious that we need to ensure variable-arity method bodies do their own arity-checking, so that direct calls from indy or Java do not cause array index errors. This PR adds such arity-checking to all such methods, following these rules:
Methods should do arity-checking manually if:
Methods do not need a manual check if they do not have minimums or maximums, or if they only pass their argument list to another variable-arity method that does a manual check.
This PR also removes arity-checking from the generated invokers, to avoid double-checking.
The main risk from this change lies in third-party extension code that has variable-arity methods but no manual checking. Passing incorrect numbers of arguments to these methods may trigger an array index error, as it would segfault in MRI (which also does not automatically check arity).