summaryrefslogtreecommitdiff
path: root/class.c
Commit message (Collapse)AuthorAgeFilesLines
* Make Module#prepend affect the iclasses of the moduleJeremy Evans2020-06-181-0/+7
| | | | | | | | | | | | 3556a834a2847e52162d1d3302d4c64390df1694 added support for Module#include to affect the iclasses of the module. It didn't add support for Module#prepend because there were bugs in the object model and GC at the time that prevented it. Those problems have been addressed in ad729a1d11c6c57efd2e92803b4e937db0f75252 and 98286e9850936e27e8ae5e4f20858cc9c13d2dde, and now adding support for it is straightforward and does not break any tests or specs. Fixes [Bug #9573]
* Assert iclass property and remove dead codeAlan Wu2020-06-161-6/+2
| | | Iclass objects are never made from other iclass objects.
* Ensure origins for all included, prepended, and refined modulesJeremy Evans2020-06-031-28/+98
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes various issues when a module is included in or prepended to a module or class, and then refined, or refined and then included or prepended to a module or class. Implement by renaming ensure_origin to rb_ensure_origin, making it non-static, and calling it when refining a module. Fix Module#initialize_copy to handle origins correctly. Previously, Module#initialize_copy did not handle origins correctly. For example, this code: ```ruby module B; end class A def b; 2 end prepend B end a = A.dup.new class A def b; 1 end end p a.b ``` Printed 1 instead of 2. This is because the super chain for a.singleton_class was: ``` a.singleton_class A.dup B(iclass) B(iclass origin) A(origin) # not A.dup(origin) ``` The B iclasses would not be modified, so the includer entry would be still be set to A and not A.dup. This modifies things so that if the class/module has an origin, all iclasses between the class/module and the origin are duplicated and have the correct includer entry set, and the correct origin is created. This requires other changes to make sure all tests still pass: * rb_undef_methods_from doesn't automatically handle classes with origins, so pass it the origin for Comparable when undefing methods in Complex. This fixed a failure in the Complex tests. * When adding a method, the method cache was not cleared correctly if klass has an origin. Clear the method cache for the klass before switching to the origin of klass. This fixed failures in the autoload tests related to overridding require, without breaking the optimization tests. Also clear the method cache for both the module and origin when removing a method. * Module#include? is fixed to skip origin iclasses. * Refinements are fixed to use the origin class of the module that has an origin. * RCLASS_REFINED_BY_ANY is removed as it was only used in a single place and is no longer needed. * Marshal#dump is fixed to skip iclass origins. * rb_method_entry_make is fixed to handled overridden optimized methods for modules that have origins. Fixes [Bug #16852]
* Fix origin iclass pointer for modulesJeremy Evans2020-05-221-5/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a module has an origin, and that module is included in another module or class, previously the iclass created for the module had an origin pointer to the module's origin instead of the iclass's origin. Setting the origin pointer correctly requires using a stack, since the origin iclass is not created until after the iclass itself. Use a hidden ruby array to implement that stack. Correctly assigning the origin pointers in the iclass caused a use-after-free in GC. If a module with an origin is included in a class, the iclass shares a method table with the module and the iclass origin shares a method table with module origin. Mark iclass origin with a flag that notes that even though the iclass is an origin, it shares a method table, so the method table should not be garbage collected. The shared method table will be garbage collected when the module origin is garbage collected. I've tested that this does not introduce a memory leak. This change caused a VM assertion failure, which was traced to callable method entries using the incorrect defined_class. Update rb_vm_check_redefinition_opt_method and find_defined_class_by_owner to treat iclass origins different than class origins to avoid this issue. This also includes a fix for Module#included_modules to skip iclasses with origins. Fixes [Bug #16736]
* Revert "Fix origin iclass pointer for modules"Jeremy Evans2020-05-221-19/+5
| | | | | | | This reverts commit c745a60634260ba2080d35af6fdeaaae86fe5193. This triggers a VM assertion. Reverting until the issue can be debugged.
* Fix origin iclass pointer for modulesJeremy Evans2020-05-221-5/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | If a module has an origin, and that module is included in another module or class, previously the iclass created for the module had an origin pointer to the module's origin instead of the iclass's origin. Setting the origin pointer correctly requires using a stack, since the origin iclass is not created until after the iclass itself. Use a hidden ruby array to implement that stack. Correctly assigning the origin pointers in the iclass caused a use-after-free in GC. If a module with an origin is included in a class, the iclass shares a method table with the module and the iclass origin shares a method table with module origin. Mark iclass origin with a flag that notes that even though the iclass is an origin, it shares a method table, so the method table should not be garbage collected. The shared method table will be garbage collected when the module origin is garbage collected. I've tested that this does not introduce a memory leak. This also includes a fix for Module#included_modules to skip iclasses with origins. Fixes [Bug #16736]
* Synchronized non-inline version rb_scan_args with the inline versionNobuyoshi Nakada2020-05-211-16/+19
|
* sed -i 's|ruby/impl|ruby/internal|'卜部昌平2020-05-111-1/+1
| | | | To fix build failures.
* sed -i s|ruby/3|ruby/impl|g卜部昌平2020-05-111-1/+1
| | | | This shall fix compile errors.
* Make rb_scan_args implementations sameNobuyoshi Nakada2020-04-121-26/+40
| | | | | between rb_scan_args_set and rb_scan_args_assign + rb_scan_args_result.
* Suppress -Wswitch warningsNobuyoshi Nakada2020-04-081-0/+2
|
* Merge pull request #2991 from shyouhei/ruby.h卜部昌平2020-04-081-2/+2
| | | Split ruby.h
* Make Module#include affect the iclasses of the moduleJeremy Evans2020-02-271-0/+20
| | | | | | | | | | | When calling Module#include, if the receiver is a module, walk the subclasses list and include the argument module in each iclass. This does not affect Module#prepend, as fixing that is significantly more involved. Fixes [Bug #9573]
* Introduce disposable call-cache.Koichi Sasada2020-02-221-10/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | This patch contains several ideas: (1) Disposable inline method cache (IMC) for race-free inline method cache * Making call-cache (CC) as a RVALUE (GC target object) and allocate new CC on cache miss. * This technique allows race-free access from parallel processing elements like RCU. (2) Introduce per-Class method cache (pCMC) * Instead of fixed-size global method cache (GMC), pCMC allows flexible cache size. * Caching CCs reduces CC allocation and allow sharing CC's fast-path between same call-info (CI) call-sites. (3) Invalidate an inline method cache by invalidating corresponding method entries (MEs) * Instead of using class serials, we set "invalidated" flag for method entry itself to represent cache invalidation. * Compare with using class serials, the impact of method modification (add/overwrite/delete) is small. * Updating class serials invalidate all method caches of the class and sub-classes. * Proposed approach only invalidate the method cache of only one ME. See [Feature #16614] for more details.
* Hoisted out `rb_scan_args_result`Nobuyoshi Nakada2020-02-141-8/+11
|
* Make `rb_scan_args_kw` inline tooNobuyoshi Nakada2020-02-031-13/+2
|
* Moved runtime assignemntsNobuyoshi Nakada2020-02-031-56/+48
| | | | | | Separate assignemnts of dynamically given runtime values in `rb_scan_args_assign` from parsing statically given format in `rb_scan_args_parse`.
* `struct rb_scan_args_t::vargs` is never usedNobuyoshi Nakada2020-02-031-1/+0
|
* Removed no longer used variable `last_hash`Nobuyoshi Nakada2020-02-021-6/+1
| | | | | | | | | 1. By substituting `n_var` with its initializer, `0 < n_var` is equivalent to `argc > argi + n_trail`. 2. As `argi` is non-negative, so `argi + n_trail >= n_trail`, and the above expression is equivalent to `argc > n_trail`. 3. Therefore, `f_last` is always false, and `last_hash` is no longer used.
* Clarify documentation for Module#included_modules and Module#included?Marc-Andre Lafortune2020-01-161-5/+10
| | | | [DOC] [ci skip] [Bug #8841]
* Remove unused tmp_buffer in class.cKazuhiro NISHIYAMA2020-01-051-11/+0
| | | | ref 44a164c26f5371519636585d8ba7aa59f489442e and beae6cbf0fd8b6619e5212552de98022d4c4d4d4
* Remove unused last_idx in class.cKazuhiro NISHIYAMA2020-01-051-6/+4
| | | | ref c7f01d889becbeffc4254e1b0b7faecb80ea3f3e and beae6cbf0fd8b6619e5212552de98022d4c4d4d4
* Fix unused warningsKazuhiro NISHIYAMA2020-01-031-1/+0
| | | | | | | | | | | | | | | | | http://ci.rvm.jp/results/trunk_gcc7@silicon-docker/2539622 ``` /tmp/ruby/v2/src/trunk_gcc7/class.c: In function 'rb_scan_args_parse': /tmp/ruby/v2/src/trunk_gcc7/class.c:1971:12: warning: unused variable 'tmp_buffer' [-Wunused-variable] VALUE *tmp_buffer = arg->tmp_buffer; ^~~~~~~~~~ ``` ``` In file included from /tmp/ruby/v2/src/trunk_gcc7/vm_insnhelper.c:1895:0, from /tmp/ruby/v2/src/trunk_gcc7/vm.c:349: /tmp/ruby/v2/src/trunk_gcc7/vm_args.c:212:1: warning: 'args_stored_kw_argv_to_hash' defined but not used [-Wunused-function] args_stored_kw_argv_to_hash(struct args_info *args) ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ```
* Fully separate positional arguments and keyword argumentsJeremy Evans2020-01-021-65/+5
| | | | | | | | | | | | | | | | | | | | | | | | This removes the warnings added in 2.7, and changes the behavior so that a final positional hash is not treated as keywords or vice-versa. To handle the arg_setup_block splat case correctly with keyword arguments, we need to check if we are taking a keyword hash. That case didn't have a test, but it affects real-world code, so add a test for it. This removes rb_empty_keyword_given_p() and related code, as that is not needed in Ruby 3. The empty keyword case is the same as the no keyword case in Ruby 3. This changes rb_scan_args to implement keyword argument separation for C functions when the : character is used. For backwards compatibility, it returns a duped hash. This is a bad idea for performance, but not duping the hash breaks at least Enumerator::ArithmeticSequence#inspect. Instead of having RB_PASS_CALLED_KEYWORDS be a number, simplify the code by just making it be rb_keyword_given_p().
* decouple internal.h headers卜部昌平2019-12-261-3/+11
| | | | | | | | | | | | | | | | | | Saves comitters' daily life by avoid #include-ing everything from internal.h to make each file do so instead. This would significantly speed up incremental builds. We take the following inclusion order in this changeset: 1. "ruby/config.h", where _GNU_SOURCE is defined (must be the very first thing among everything). 2. RUBY_EXTCONF_H if any. 3. Standard C headers, sorted alphabetically. 4. Other system headers, maybe guarded by #ifdef 5. Everything else, sorted alphabetically. Exceptions are those win32-related headers, which tend not be self- containing (headers have inclusion order dependencies).
* Reword keyword arguments warning messages to convey these are deprecation ↵Marc-Andre Lafortune2019-12-231-3/+3
| | | | warnings
* vm_args.c: rephrase the warning message of keyword argument separationYusuke Endoh2019-12-201-1/+1
| | | | | | | | | | (old) test.rb:4: warning: The last argument is used as the keyword parameter test.rb:1: warning: for `foo' defined here; maybe ** should be added to the call? (new) test.rb:4: warning: The last argument is used as keyword parameters; maybe ** should be added to the call test.rb:1: warning: The called method `foo' is defined here
* Make super in instance_eval in method in module raise TypeErrorJeremy Evans2019-12-121-0/+1
| | | | | | | | | | | | | | | | | | | | | | | This makes behavior the same as super in instance_eval in method in class. The reason this wasn't implemented before is that there is a check to determine if the self in the current context is of the expected class, and a module itself can be included in multiple classes, so it doesn't have an expected class. Implementing this requires giving iclasses knowledge of which class created them, so that super call in the module method knows the expected class for super calls. This reference is called includer, and should only be set for iclasses. Note that the approach Ruby uses in this check is not robust. If you instance_eval another object of the same class and call super, instead of an TypeError, you get super called with the instance_eval receiver instead of the method receiver. Truly fixing super would require keeping a reference to the super object (method receiver) in each frame where scope has changed, and using that instead of current self when calling super. Fixes [Bug #11636]
* Merged common statements [Bug #16242]Nobuyoshi Nakada2019-11-281-7/+1
|
* Removed unused variable [Bug #16242]Nobuyoshi Nakada2019-11-281-1/+0
|
* Make prepending a refined module after inclusion not break refinementsJeremy Evans2019-11-281-8/+19
| | | | | | | | | | | | | | | | | | | | | | | | | After the previous commit, this was still broken. The reason it was broken is that a refined module that hasn't been prepended to yet keeps the refined methods in the module's method table. When prepending, the module's method table is moved to the origin iclass, and then the refined methods are moved from the method table to a new method table in the module itself. Unfortunately, that means that if a class has included the module, prepending breaks the refinements, because when the methods are moved from the origin iclass method table to the module method table, they are removed from the method table from the iclass created when the module was included earlier. Fix this by always creating an origin class when including a module that has any refinements, even if the refinements are not currently used. I wasn't sure the best way to do that. The approach I choose was to use an object flag. The flag is set on the module when Module#refine is called, and if the flag is present when the module is included in another module or class, an origin iclass is created for the module. Fixes [Bug #13446]
* Honor refinements for modules that prepend other modulesJeremy Evans2019-11-281-6/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This previously did not work, and the reason it did not work is that: 1) Refining a module or class that prepends other modules places the refinements in the class itself and not the origin iclass. 2) Inclusion of a module that prepends other modules skips the module itself, including only iclasses for the prepended modules and the origin iclass. Those two behaviors combined meant that the method table for the refined methods for the included module never ends up in the method lookup chain for the class including the module. Fix this by not skipping the module itself when the module is included. This requires some code rearranging in rb_include_class_new to make sure the correct method tables and origin settings are used for the created iclass. As origin iclasses shouldn't be exposed to Ruby, this also requires skipping modules that have origin iclasses in Module#ancestors (classes that have origin iclasses were already skipped). Fixes [Bug #16242]
* Deprecate taint/trust and related methods, and make the methods no-opsJeremy Evans2019-11-181-12/+0
| | | | | | This removes the related tests, and puts the related specs behind version guards. This affects all code in lib, including some libraries that may want to support older versions of Ruby.
* Let the arrays for the singleton and instance method reflection helpers be ↵Lourens Naudé2019-10-291-2/+2
| | | | initialized to the methods count
* Simplify rb_define_module_idAlan Wu2019-10-101-5/+1
|
* Prefer st_is_member over st_lookup with 0Ben Woosley2019-10-091-1/+1
| | | | The st_is_member DEFINE has simpler semantics, for more readable code.
* Revert https://github.com/ruby/ruby/pull/2486卜部昌平2019-10-031-33/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commits: 10d6a3aca7 8ba48c1b85 fba8627dc1 dd883de5ba 6c6a25feca 167e6b48f1 7cb96d41a5 3207979278 595b3c4fdd 1521f7cf89 c11c5e69ac cf33608203 3632a812c0 f56506be0d 86427a3219 . The reason for the revert is that we observe ABA problem around inline method cache. When a cache misshits, we search for a method entry. And if the entry is identical to what was cached before, we reuse the cache. But the commits we are reverting here introduced situations where a method entry is freed, then the identical memory region is used for another method entry. An inline method cache cannot detect that ABA. Here is a code that reproduce such situation: ```ruby require 'prime' class << Integer alias org_sqrt sqrt def sqrt(n) raise end GC.stress = true Prime.each(7*37){} rescue nil # <- Here we populate CC class << Object.new; end # These adjacent remove-then-alias maneuver # frees a method entry, then immediately # reuses it for another. remove_method :sqrt alias sqrt org_sqrt end Prime.each(7*37).to_a # <- SEGV ```
* refactor constify most of rb_method_entry_t卜部昌平2019-09-301-3/+3
| | | | | | | | | | | Now that we have eliminated most destructive operations over the rb_method_entry_t / rb_callable_method_entry_t, let's make them mostly immutabe and mark them const. One exception is rb_export_method(), which destructively modifies visibilities of method entries. I have left that operation as is because I suspect that destructiveness is the nature of that function.
* refactor add rb_method_entry_from_template卜部昌平2019-09-301-12/+5
| | | | | | Tired of rb_method_entry_create(..., rb_method_definition_create( ..., &(rb_method_foo_t) {...})) maneuver. Provide a function that does the thing to reduce copy&paste.
* refactor delete rb_method_entry_copy卜部昌平2019-09-301-11/+39
| | | | | | The deleted function was to destructively overwrite existing method entries, which is now considered to be a bad idea. Delete it, and assign a newly created method entry instead.
* Adjusted spaces [ci skip]Nobuyoshi Nakada2019-09-271-2/+2
|
* Make rb_scan_args handle keywords more similar to Ruby methods (#2460)Jeremy Evans2019-09-251-60/+186
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Cfuncs that use rb_scan_args with the : entry suffer similar keyword argument separation issues that Ruby methods suffer if the cfuncs accept optional or variable arguments. This makes the following changes to : handling. * Treats as **kw, prompting keyword argument separation warnings if called with a positional hash. * Do not look for an option hash if empty keywords are provided. For backwards compatibility, treat an empty keyword splat as a empty mandatory positional hash argument, but emit a a warning, as this behavior will be removed in Ruby 3. The argument number check needs to be moved lower so it can correctly handle an empty positional argument being added. * If the last argument is nil and it is necessary to treat it as an option hash in order to make sure all arguments are processed, continue to treat the last argument as the option hash. Emit a warning in this case, as this behavior will be removed in Ruby 3. * If splitting the keyword hash into two hashes, issue a warning, as we will not be splitting hashes in Ruby 3. * If the keyword argument is required to fill a mandatory positional argument, continue to do so, but emit a warning as this behavior will be going away in Ruby 3. * If keyword arguments are provided and the last argument is not a hash, that indicates something wrong. This can happen if a cfunc is calling rb_scan_args multiple times, and providing arguments that were not passed to it from Ruby. Callers need to switch to the new rb_scan_args_kw function, which allows passing of whether keywords were provided. This commit fixes all warnings caused by the changes above. It switches some function calls to *_kw versions with appropriate kw_splat flags. If delegating arguments, RB_PASS_CALLED_KEYWORDS is used. If creating new arguments, RB_PASS_KEYWORDS is used if the last argument is a hash to be treated as keywords. In open_key_args in io.c, use rb_scan_args_kw. In this case, the arguments provided come from another C function, not Ruby. The last argument may or may not be a hash, so we can't set keyword argument mode. However, if it is a hash, we don't want to warn when treating it as keywords. In Ruby files, make sure to appropriately use keyword splats or literal keywords when calling Cfuncs that now issue keyword argument separation warnings through rb_scan_args. Also, make sure not to pass nil in place of an option hash. Work around Kernel#warn warnings due to problems in the Rubygems override of the method. There is an open pull request to fix these issues in Rubygems, but part of the Rubygems tests for their override fail on ruby-head due to rb_scan_args not recognizing empty keyword splats, which this commit fixes. Implementation wise, adding rb_scan_args_kw is kind of a pain, because rb_scan_args takes a variable number of arguments. In order to not duplicate all the code, the function internals need to be split into two functions taking a va_list, and to avoid passing in a ton of arguments, a single struct argument is used to handle the variables previously local to the function.
* variable.c: Rename rb_st_copy to rb_iv_tbl_copyYusuke Endoh2019-09-221-2/+2
| | | | | | | | | This function was created as a variant of st_copy with firing write barrier. It should have more explicit name, such as st_copy_with_write_barrier. But because it is used only for copying iv_tbl, so I rename it to rb_iv_tbl_copy now. If we face other use case than iv_tbl, we may want to rename it to more general name.
* Separate keyword arguments from positional argumentsYusuke Endoh2019-08-301-2/+1
| | | | And, allow non-symbol keys as a keyword arugment
* drop-in type check for rb_define_singleton_method卜部昌平2019-08-291-0/+3
| | | | | | We can check the function pointer passed to rb_define_singleton_method like how we do so in rb_define_method. Doing so revealed many arity mismatches.
* drop-in type check for rb_define_private_method卜部昌平2019-08-291-0/+3
| | | | | | | We can check the function pointer passed to rb_define_private_method like how we do so in rb_define_method. Doing so revealed some problematic usages of rb_obj_dummy. They had to be split according to their arity.
* drop-in type check for rb_define_protected_method卜部昌平2019-08-291-0/+3
| | | | | | We can check the function pointer passed to rb_define_protected_method like how we do so in rb_define_method. This changeset revealed no prototypes mismatches.
* drop-in type check for rb_define_method_id卜部昌平2019-08-291-0/+3
| | | | | | We can check the function pointer passed to rb_define_method_id like how we do so in rb_define_method. This method is relatively rarely used so there are less problems found than the other APIs.
* drop-in type check for rb_define_global_function卜部昌平2019-08-291-1/+3
| | | | | | We can check the function pointer passed to rb_define_global_function like we do so in rb_define_method. It turns out that almost anybody is misunderstanding the API.
* drop-in type check for rb_define_module_function卜部昌平2019-08-291-2/+3
| | | | | | We can check the function pointer passed to rb_define_module_function like how we do so in rb_define_method. The difference is that this changeset reveales lots of atiry mismatches.