aboutsummaryrefslogtreecommitdiffstats
path: root/vm_args.c
Commit message (Collapse)AuthorAgeFilesLines
* Kernel#lambda: return forwarded block as non-lambda procAlan Wu2019-12-211-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | Before this commit, Kernel#lambda can't tell the difference between a directly passed literal block and one passed with an ampersand. A block passed with an ampersand is semantically speaking already a non-lambda proc. When Kernel#lambda receives a non-lambda proc, it should simply return it. Implementation wise, when the VM calls a method with a literal block, it places the code for the block on the calling control frame and passes a pointer (block handler) to the callee. Before this commit, the VM forwards block arguments by simply forwarding the block handler, which leaves the slot for block code unused when a control frame forwards its block argument. I use the vacant space to indicate that a frame has forwarded its block argument and inspect that in Kernel#lambda to detect forwarded blocks. This is a very ad-hoc solution and relies *heavily* on the way block passing works in the VM. However, it's the most self-contained solution I have. [Bug #15620]
* vm_args.c: rephrase the warning message of keyword argument separationYusuke Endoh2019-12-201-8/+8
| | | | | | | | | | (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
* Manage deprecation warnings about keyword argumentNobuyoshi Nakada2019-12-191-0/+2
|
* Adjusted the formatNobuyoshi Nakada2019-12-191-2/+4
|
* vm_core.h (iseq_unique_id): prefer uintptr_t instead of unsigned longYusuke Endoh2019-12-101-8/+8
| | | | It produced a warning about type cast in LLP64 (i.e., windows).
* vm_args.c (rb_warn_check): Use iseq_unique_id instead of its pointerYusuke Endoh2019-12-091-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | (This is the second try of 036bc1da6c6c9b0fa9b7f5968d897a9554dd770e.) If iseq is GC'ed, the pointer of iseq may be reused, which may hide a deprecation warning of keyword argument change. http://ci.rvm.jp/results/trunk-test1@phosphorus-docker/2474221 ``` 1) Failure: TestKeywordArguments#test_explicit_super_kwsplat [/tmp/ruby/v2/src/trunk-test1/test/ruby/test_keyword.rb:549]: --- expected +++ actual @@ -1 +1 @@ -/The keyword argument is passed as the last hash parameter.* for `m'/m +"" ``` This change ad-hocly adds iseq_unique_id for each iseq, and use it instead of iseq pointer. This covers the case where caller is GC'ed. Still, the case where callee is GC'ed, is not covered. But anyway, it is very rare that iseq is GC'ed. Even when it occurs, it just hides some warnings. It's no big deal.
* Revert "vm_args.c (rb_warn_check): Use iseq_unique_id instead of its pointer"Yusuke Endoh2019-12-091-5/+1
| | | | | | | | | This reverts commit 036bc1da6c6c9b0fa9b7f5968d897a9554dd770e. This caused a failure on iseq_binary mode. http://ci.rvm.jp/results/trunk-iseq_binary@silicon-docker/2474587 Numbering iseqs is not trivial due to dump/load.
* Revert "vm_args.c (rb_warn_check): Use unique_id * 2 instead of unique_id"Yusuke Endoh2019-12-091-1/+1
| | | | This reverts commit 751a9b32e5a53336768eb878de1827245a3292bf.
* vm_args.c (rb_warn_check): Use unique_id * 2 instead of unique_idYusuke Endoh2019-12-091-1/+1
| | | | The function assumed that the LSB of `callee` was 0.
* vm_args.c (rb_warn_check): Use iseq_unique_id instead of its pointerYusuke Endoh2019-12-091-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | If iseq is GC'ed, the pointer of iseq may be reused, which may hide a deprecation warning of keyword argument change. http://ci.rvm.jp/results/trunk-test1@phosphorus-docker/2474221 ``` 1) Failure: TestKeywordArguments#test_explicit_super_kwsplat [/tmp/ruby/v2/src/trunk-test1/test/ruby/test_keyword.rb:549]: --- expected +++ actual @@ -1 +1 @@ -/The keyword argument is passed as the last hash parameter.* for `m'/m +"" ``` This change ad-hocly adds iseq_unique_id for each iseq, and use it instead of iseq pointer. This covers the case where caller is GC'ed. Still, the case where callee is GC'ed, is not covered. But anyway, it is very rare that iseq is GC'ed. Even when it occurs, it just hides some warnings. It's no big deal.
* vm_args.c: make the keyword deprecation message helpfulYusuke Endoh2019-12-031-3/+3
| | | | | | | | ``` $ ./miniruby -e 'def foo(kw: 1); end; h = {kw: 1}; foo(h)' -e:1: warning: The last argument is used as the keyword parameter -e:1: warning: for `foo' defined here; maybe ** should be added to the call? ```
* Reduce duplicated warnings for the change of Ruby 3 keyword argumentsYusuke Endoh2019-11-291-10/+61
| | | | | | | | | | | | | | | By this change, the following code prints only one warning. ``` def foo(**opt); end 100.times { foo({kw:1}) } ``` A global variable `st_table *caller_to_callees` is a map from caller to a set of callee methods. It remembers that a warning is already printed for each pair of caller and callee. [Feature #16289]
* Don't modify rest array when using ruby2_keywordsJeremy Evans2019-11-271-2/+1
| | | | | | Previously, the rest array was modified, but it turns out that is not necessary. Not modifying the rest array fixes cases when the rest array is used more than once.
* Always forward declaration is neededNobuyoshi Nakada2019-11-201-1/+2
| | | | | | `rb_resolve_refined_method_callable` is referenced in `refine_sym_proc_call`, even when pre-compiling mjit header on mswin.
* make functions static卜部昌平2019-11-191-0/+3
| | | | | | | These functions are used from within a compilation unit so we can make them static, for better binary size. This changeset reduces the size of generated ruby binary from 26,590,128 bytes to 26,584,472 bytes on my macihne.
* Handle case where ruby2_keywords method splats to ruby2_keywords methodJeremy Evans2019-10-241-0/+3
| | | | | | Previously, the keyword hash was duped (which results in a regular hash), but the dup was not marked as a keyword hash, causing the hash not to be marked as keyword hash even though it should be.
* Dup hash with keyword flag when converted to keywordsJeremy Evans2019-10-151-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | When ruby2_keywords is used on a method, keywords passed to the method are flagged. When the hash is passed as the last element of an argument splat to another method, the hash should be treated as a keyword splat. When keyword splatting a hash, a duplicate of the hash is made. So when auto-splatting the hash with the keyword flag, a duplicate of the hash should also be made. This fixes cases where the hash is later passed to another method and would be treated as keywords there: class Object ruby2_keywords def foo(*a) bar(*a) end def bar(*a) baz(*a) end def baz(*a, **kw) [a, kw] end end foo(:a=>1) Previously, this would pass the :a=>1 as keywords to bar and also as keywords to baz. Now it only passes :a=>1 as keywords to bar, but bar passes :a=>1 as a positional hash to baz (which in this case generates a warning in 2.7).
* Remove VM_NO_KEYWORDS, replace with RB_NO_KEYWORDSJeremy Evans2019-09-291-1/+1
| | | | | VM_NO_KEYWORDS was introduced first in vm_core.h, but it is best to only use a single definition for this.
* Adjusted spaces [ci skip]Nobuyoshi Nakada2019-09-271-6/+7
|
* Add rb_adjust_argv_kw_splat to internal.hJeremy Evans2019-09-261-1/+0
| | | | | We are calling this in a few other files, it is better to have it in a header than adding prototypes to the other files.
* Add Module#ruby2_keywords for passing keywords through regular argument splatsJeremy Evans2019-09-251-10/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This approach uses a flag bit on the final hash object in the regular splat, as opposed to a previous approach that used a VM frame flag. The hash flag approach is less invasive, and handles some cases that the VM frame flag approach does not, such as saving the argument splat array and splatting it later: ruby2_keywords def foo(*args) @args = args bar end def bar baz(*@args) end def baz(*args, **kw) [args, kw] end foo(a:1) #=> [[], {a: 1}] foo({a: 1}, **{}) #=> [[{a: 1}], {}] foo({a: 1}) #=> 2.7: [[], {a: 1}] # and warning foo({a: 1}) #=> 3.0: [[{a: 1}], {}] It doesn't handle some cases that the VM frame flag handles, such as when the final hash object is replaced using Hash#merge, but those cases are probably less common and are unlikely to properly support keyword argument separation. Use ruby2_keywords to handle argument delegation in the delegate library.
* Fix keyword argument separation issues with sym procs when using refinementsJeremy Evans2019-09-171-2/+11
| | | | | | | | | | | | Make sure that vm_yield_with_cfunc can correctly set the empty keyword flag by passing 2 as the kw_splat value when calling it in vm_invoke_ifunc_block. Make sure calling.kw_splat is set to 1 and not 128 in vm_sendish, so we can safely check for different kw_splat values. vm_args.c needs to call add_empty_keyword, and to make JIT happy, the function needs to be exported. Rename the function to rb_adjust_argv_kw_splat to more accurately reflect what it does, and mark it as MJIT exported.
* Pass keyword argument flag when rb_call_super_kw calls method_missingJeremy Evans2019-09-171-2/+2
| | | | | | | | This makes method_missing take a flag for whether keyword arguments were passed. Adds tests both for rb_call_super_kw usage as well as general usage of super calling method_missing in Ruby methods.
* Emit missing keyword argument separation warnings for define_methodJeremy Evans2019-09-111-8/+24
| | | | | | | | | Previously, the warning functions skipped warning in these cases. This removes the skipping, and uses a less descriptive warning instead. This affected both last argument to keyword warnings and keyword split warnings.
* Fix invalid keyword argument separation warning for delegating callsJeremy Evans2019-09-081-7/+2
| | | | | | | | | | | | | | | | | | | | This removes an invalid keyword argument separation warning for code such as: ```ruby def foo(arg) arg end kw = {} foo(*[1], **kw) ``` This warning was caused because the remove_empty_keyword_hash was set based on a comparison with two variables, and in this case, one of the variables was updated after the check and we need to use the updated variable. Simplify things by just inlining the comparison.
* Enable keyword argument warnings when called from CJeremy Evans2019-09-061-6/+3
| | | | | | Previously, Ruby did not warn in these cases, and in some cases did not have the same behavior. This makes calls from C handled the same way as calls from Ruby.
* Mark rb_warn_keyword_to_last_hash as static inlineJeremy Evans2019-09-051-1/+1
| | | | mame pointed out that vm_args.c is included in vm_insnhelper.c.
* Mark rb_warn_keyword_to_last_hash at MJIT_FUNC_EXPORTEDJeremy Evans2019-09-051-1/+1
| | | | Hopefully this fixes MJIT errors on AppVeyor.
* Convert empty keyword hash to required positional argument and warnJeremy Evans2019-09-051-14/+32
| | | | | | | | | | | | | | | | | | | | | | | | | In general, we want to ignore empty keyword hashes. The only case where we want to allow them for backwards compatibility is when they are necessary to satify the final required positional argument. In that case, we want to not ignore them, but we do want to warn, as that will be going away in Ruby 3. This commit implements this support for regular methods and attr_writer methods. In order to allow send to forward arguments correctly, send no longer removes empty keyword hashes. It is the responsibility of the final method to remove the empty keyword hashes now. This change was necessary as otherwise send could remove the empty keyword hashes before the regular or attr_writer methods could move them to required positional arguments. For completeness, add tests for keyword handling regular methods calls. This makes rb_warn_keyword_to_last_hash non-static in vm_args.c so it can be reused in vm_insnhelper.c, and also moves declarations before statements in the rb_warn_* functions in vm_args.c.
* vm_argc.c (vm_caller_setup_arg_kw): "cfunc" argument is no longer usedYusuke Endoh2019-09-051-1/+1
|
* Set calling->kw_splat = 1 in vm_caller_setup_arg_kwYusuke Endoh2019-09-051-0/+1
| | | | | | | | | | | | | | There are two styles that argv contains keyword arguments: one is VM_CALL_KWARG which contains value elements in argv (to avoid a hash object creation if possible), and the other is VM_CALL_KW_SPLAT which contains one last hash in argv. vm_caller_setup_arg_kw translates argv from the VM_CALL_KWARG style to the VM_CALL_KW_SPLAT style. `calling->kw_splat` means that argv is the VM_CALL_KW_SPLAT style. So, instead of setting `calling->kw_splat` at many places, it would be better to do so when vm_caller_setup_arg_kw is called.
* Add rb_funcall_with_block_kwJeremy Evans2019-09-051-2/+2
| | | | | | | | | | | | | | | | | This is needed for C functions to call methods with keyword arguments. This is a copy of rb_funcall_with_block with an extra argument for the keyword flag. There isn't a clean way to implement this that doesn't involve changing a lot of function signatures, because rb_call doesn't support a way to mark that the call has keyword arguments. So hack this in using a CALL_PUBLIC_KW call_type, which we switch for CALL_PUBLIC later in the call stack. We do need to modify rm_vm_call0 to take an argument for whether keyword arguments are used, since the call_type is no longer available at that point. Use the passed in value to set the appropriate keyword flag in both calling and ci_entry.
* Propagate kw_splat informationYusuke Endoh2019-09-051-1/+4
| | | | | | | The kw_splat flag is whether the original call passes keyword or not. Some types of methods (e.g., bmethod and sym_proc) drops the information. This change tries to propagate the flag to the final callee, as far as I can.
* Split warning messages for tag-jumpNobuyoshi Nakada2019-09-011-9/+18
|
* Add rb_iseq_locationJeremy Evans2019-08-301-4/+4
| | | | This wraps iseq_location and should fix the leaked global test.
* Use more accurate source location in keyword argument separation warningsJeremy Evans2019-08-301-16/+12
| | | | | | | | This shows locations in places it didn't before, such as for proc calls, and fixes the location for super calls. This requires making iseq_location non-static and MJIT exported, which I hope will not cause problems.
* Warn for keyword to last hash parameter when method has no optional/rest ↵Jeremy Evans2019-08-301-30/+34
| | | | | | | | | parameters Previously, there was no warning in this case, even though we will be changing the behavior in Ruby 3. Fixes [Bug #14130]
* Remove a verbose warning that is no longer neededJeremy Evans2019-08-301-11/+0
| | | | This warns about a case that we will continue to support.
* When splitting a keyword hash, dup it first to not mutate itJeremy Evans2019-08-301-0/+1
|
* Implement keyword argument to last positional hash emulationJeremy Evans2019-08-301-1/+27
| | | | | | | | | | | For methods that accept keyword arguments but do not accept a keyword splat, if a keyword splat is passed, or keywords are used with a non-symbol key, check the hash. If the hash contains all symbols, keep the same behavior as before. If the hash contains all non-symbols, move the hash to the last positional hash and warn. If the hash contains symbols and non-Symbols, split the hash and use the symbol keys for the keyword hash and non-symbol keys for the positional hash and warn.
* Make keyword_hash_split staticJeremy Evans2019-08-301-1/+1
|
* Support **nil syntax for specifying a method does not accept keyword argumentsJeremy Evans2019-08-301-0/+4
| | | | | | | | | This syntax means the method should be treated as a method that uses keyword arguments, but no specific keyword arguments are supported, and therefore calling the method with keyword arguments will raise an ArgumentError. It is still allowed to double splat an empty hash when calling the method, as that does not pass any keyword arguments.
* Restore splitting of hashes into positional and keyword arguments, add warningJeremy Evans2019-08-301-12/+62
| | | | | | | | | | | | | | This restores compatibility with Ruby 2.6, splitting the last positional hash into positional and keyword arguments if it contains both symbol and non-symbol keys. However, in this case it will warn, as the behavior in Ruby 3 will be to not split the hash and keep it as a positional argument. This does not affect the handling of mixed symbol and non-symbol keys in bare keywords. Those are still treated as keywords now, as they were before this patch. This results in different behavior than Ruby 2.6, which would split the bare keywords and use the non-Symbol keys as a positional arguments.
* Only promote last hash to keyword if all keys are symbolsJeremy Evans2019-08-301-6/+29
| | | | | | | | If all keys are not symbols, then the non-symbol keys would not be treated as keywords in previous versions. It doesn't make sense to treat these hashes as keywords to break compatibility and warn about behavior changes in Ruby 2.7 when the Ruby 3.0 behavior will be the same as the Ruby 2.6 for these hashes.
* Fix hash to keyword warning to apply in all casesJeremy Evans2019-08-301-11/+9
| | | | | Previously, it only applied if the call had more positional arguments than the method it was calling accepted.
* Allow ** syntax to be used for calling methods that do not accept keywordsJeremy Evans2019-08-301-51/+19
| | | | | | | | Treat the ** syntax as passing a copy of the hash as the last positional argument. If the hash being double splatted is empty, do not add a positional argument. Remove rb_no_keyword_hash, no longer needed.
* Separate keyword arguments from positional argumentsYusuke Endoh2019-08-301-10/+108
| | | | And, allow non-symbol keys as a keyword arugment
* update Array's length correctly.Koichi Sasada2019-05-231-2/+2
| | | | | | ARRAY_ASET() does not change the length of array, so use rb_ary_push() instead of ARRAY_ASET(). It prevents updating reference on GC.compact.
* Adjusted stylesnobu2019-04-101-1/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67504 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Reverting all commits from r67479 to r67496 because of CI failureskazu2019-04-101-1/+1
| | | | | | | | Because hard to specify commits related to r67479 only. So please commit again. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67499 b2dd03c8-39d4-4d8f-98ff-823fe69b080e