Commit Graph

61 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto 90fd382a9e mruby-array-ext: implement Array#fetch with hybrid approach
Moved Array#fetch from Ruby to C using hybrid implementation for
better performance. The C implementation handles all non-block cases
with unified API that eliminates Ruby conditional logic.

Key improvements:
- Fast C implementation for common cases (no blocks)
- Shared index normalization helper reusable for other methods
- Unified C call eliminates NONE sentinel comparison in Ruby
- Block cases use C helper for index normalization

Added comprehensive test coverage including edge cases, default values,
block handling, and error message format verification. Combined tests
to focus on functionality rather than implementation details.

Co-authored-by: Atlassian Rovo Dev
2025-06-30 12:17:21 +09:00
Yukihiro "Matz" Matsumoto 87c39d3c0b mruby-array-ext: implement Array#insert in C
This commit also corrects the behavior of `Array#insert` when a negative
index is out of bounds. It now raises an `IndexError`, which is
consistent with CRuby.

Co-authored-by: Gemini <gemini@google.com>
2025-06-30 12:10:34 +09:00
Yukihiro "Matz" Matsumoto f8451045fe mruby-array-ext: implement flatten and flatten! in C
This commit replaces the Ruby implementation of  and  with a C
implementation. The new implementation is iterative and uses a stack to
avoid deep recursion, which prevents stack overflows when flattening
deeply nested arrays.

Co-authored-by: Gemini <gemini@google.com>
2025-06-30 11:55:17 +09:00
Yukihiro "Matz" Matsumoto ec7d94685d mruby-array-ext: implement fast path for uniq/uniq! in c
Co-authored-by: Gemini <gemini@google.com>
2025-06-30 10:26:43 +09:00
Yukihiro "Matz" Matsumoto 9e8cda73f6 mruby-array-ext: implement Array#fill in C
Implemented shared C argument parser and separate fill logic to eliminate code
duplication while maximizing performance. The implementation uses C implemented
__fill_parse_args for unified argument handling and __fill_exec for fast
C-based value filling.

Added comprehensive test coverage for both shared argument parsing
and C fill implementation, including range arguments, block handling,
and array extension scenarios.

Co-authored-by: Atlassian Rovo Dev
Co-authored-by: Gemini <gemini@google.com>
2025-06-30 10:26:42 +09:00
Yukihiro "Matz" Matsumoto c4464fa25a array.c: expose mrb_ary_dup() as a new C API 2025-06-29 20:46:51 +09:00
Yukihiro "Matz" Matsumoto 0afe69696c mruby-array-ext: implement Array#intersection in C and refactor Array#&
Co-authored-by: Gemini <gemini@google.com>
2025-06-29 20:46:51 +09:00
Yukihiro "Matz" Matsumoto 0725f691b4 mruby-array-ext: implement Array#union in C and refactor Array#|
Co-authored-by: Gemini <gemini@google.com>
2025-06-29 20:46:51 +09:00
Yukihiro "Matz" Matsumoto fdb0a664c6 mruby-array-ext: implement Array#difference in C and refactor Array#-
The Ruby implementation of `Array#difference` was inefficient as it
called `Array#-` repeatedly, creating intermediate arrays.

This commit replaces it with a C implementation that processes all
arguments in a single pass. The core logic is extracted into a
shared helper function, `ary_subtract_internal`, which is now used
by both `Array#-` and `Array#difference`.

Co-authored-by: Gemini <gemini@google.com>
2025-06-29 20:46:51 +09:00
Yukihiro "Matz" Matsumoto f205c2233d mruby-array-ext: increase SET_OP_HASH_THRESHOLD from 16 to 32
We have more chance to avoid hash allocation in set-like methods. Since
memory situation heavily depends on the platform, we may need to make
this threshold configurable in the future.

Co-authored-by: Atlassian Rovo Dev
2025-06-29 20:46:51 +09:00
Yukihiro "Matz" Matsumoto da813e0486 mruby-array-ext: implement Array#intersect? in C for better performance
Moved Array#intersect? implementation from Ruby to C to improve memory
usage and performance with early termination optimization. The C
implementation uses hash-based lookup for large arrays (>16 elements)
and linear search for smaller arrays.

Added comprehensive test coverage including early termination scenarios,
empty arrays, size optimization verification, and edge cases with
duplicates and large arrays.

Co-authored-by: Atlassian Rovo Dev
2025-06-29 20:46:50 +09:00
Yukihiro "Matz" Matsumoto ea5de2b8da mruby-array-ext: implement Array#& in C for better performance
Moved Array#& (set intersection) implementation from Ruby to C to improve
memory usage and performance. The C implementation uses hash-based
deduplication for large arrays (>16 elements) and linear search for
smaller arrays, following the same hybrid pattern as Array#| and Array#-.

Key improvements:
- Hash-based approach uses mrb_hash_delete_key() for proper deduplication
- Linear search approach checks result array to ensure uniqueness
- Maintains order preservation from the first array
- Eliminates temporary object creation in Ruby implementation

Added comprehensive test coverage for both small and large array scenarios,
including edge cases like no intersection, complete intersection, and
duplicate handling.

Co-authored-by: Atlassian Rovo Dev
2025-06-28 01:33:04 +09:00
Yukihiro "Matz" Matsumoto df35982297 mruby-parray-ext: implement Array#| in C for better performance
The C implementation uses hash-based deduplication for large arrays
(>16 elements) and linear search for smaller arrays, following the same
pattern as other set operations.

Co-authored-by: Atlassian Rovo Dev
2025-06-28 00:47:10 +09:00
Yukihiro "Matz" Matsumoto 409f39e911 mruby-array-ext: implement Array#- in C
Refactor Array#- to a C implementation for improved memory and performance,
especially for set operations. Uses a hybrid approach for efficiency.

Co-authored-by: Gemini <gemini@google.com>
2025-06-28 00:47:09 +09:00
Yukihiro "Matz" Matsumoto cfd90a65f7 mruby-array-ext: use presym for initialization 2024-06-14 01:41:06 +09:00
Yukihiro "Matz" Matsumoto a80f394d97 mruby-array-ext (ary_rotate_bang): mrb_ary_modify may alter buf address 2023-09-27 18:37:38 +09:00
Yukihiro "Matz" Matsumoto 629a6839fd mruby-array-ext (ary_compact_bang): skip check that is always true 2023-09-27 18:32:44 +09:00
Yukihiro "Matz" Matsumoto f65229d103 mruby-array-ext (ary_compact_bang): mrb_ary_modify may alter buf address 2023-09-27 18:30:43 +09:00
Yukihiro "Matz" Matsumoto 9822c843e9 mruby-array-ext/array.c: remove mrb_ prefix from static functions 2023-04-13 07:39:05 +09:00
Yukihiro "Matz" Matsumoto 4e5be5a288 array.c: avoid slower mrb_get_args() if possible 2023-01-25 14:10:03 +09:00
Yukihiro "Matz" Matsumoto 9c5dc42e59 small cosmetic changes.
I prefer `i++` style unless absolutely necessary.
This commit is an addition to 41e4148.
2022-11-19 17:11:56 +09:00
Yukihiro "Matz" Matsumoto c27ae4337d mruby-array-ext/array.c (mrb_ary_values_at): avoid mrb_get_args().
If your function doesn't call VM recursively, you can use mrb_get_argv()
instead of mrb_get_args(mrb, "*", ...).
2022-10-20 19:07:25 +09:00
Yukihiro "Matz" Matsumoto 5c2f3f72a4 mruby-array-ext/array.c (mrb_ary_slice_bang): refactor.
Use `mrb_ary_new_from_value()` instead of adding individual elements
using a loop.
2022-10-15 08:46:48 +09:00
Yukihiro "Matz" Matsumoto b99c389ec3 internal.h: aggregate internal functions.
Internal functions can only be called from within the library.
Functions listed in `mruby/internal.h` can be called from:

* core (src/*.c)
* gems (mrbgems/**/*.c)

But not from the application linked with `libmruby`.
2022-04-02 18:25:13 +09:00
Yukihiro "Matz" Matsumoto 0bf1ed9f2c array-ext/array.c: remove unused local variable. 2022-03-03 08:08:01 +09:00
Yukihiro "Matz" Matsumoto 5305c5c84d array.c: call mrb_ary_delete_at() directly from Array#slice!.
Avoid `mrb_funcall()`.
2022-02-26 14:21:35 +09:00
dearblue a137ef12f9 Get object properties after mrb_get_args()
ref. #5613

I checked with Valgrind, and the methods that can cause use-after-free are `Array#rotate`, `Array#rotate!`, and `String#byteslice`.
Since `String#rindex` uses `RSTRING_LEN()` indirectly inside the function, no reference to the out-of-bounds range is generated.
2021-12-30 22:34:22 +09:00
Yukihiro "Matz" Matsumoto 48b08fecba array.c: unify mrb_ary_ref and mrb_ary_entry
Use only `mrb_ary_entry` hereafter.
2021-05-27 21:43:43 +09:00
Yukihiro "Matz" Matsumoto ae4c952d2e mruby-array-ext/array.c: implement Array#rotate in C.
The Ruby version of `Array#rotate!` generated a rotated array and
replaced the receiver, but the C version rotates the receiver array
in-place. So the performance is improved a lot both in speed and memory
consumption. Look for the comments in `array.c` for the in-place rotating
algorithm, if you are interested.
2021-05-15 17:26:36 +09:00
Yukihiro "Matz" Matsumoto 9422fdbc87 mruby-array-ext/array.c: implement Array#compact in C. 2021-05-14 10:39:41 +09:00
Yukihiro "Matz" Matsumoto 17ecf14511 Revert "Minimize the changes in #5277"
This reverts commit dc51d89ac2.
2021-01-26 10:57:07 +09:00
Yukihiro "Matz" Matsumoto dc51d89ac2 Minimize the changes in #5277
Instead of including `mruby/presym.h` everywhere, we provided the
fallback `mruby/presym.inc` under `include/mruby` directory, and specify
`-I<build-dir>/include` before `-I<top-dir>/include` in `presym.rake`.
So even when someone drops `-I<build-dir>/include` in compiler options,
it just compiles without failure.
2021-01-22 18:38:53 +09:00
KOBAYASHI Shuji 90b53f4c29 Avoid including presym.inc in existing header files
Addressed an issue where existing programs linking `libmruby.a` could only
be built by adding `<build-dir>/include` to compiler's include path.
2021-01-11 09:21:07 +09:00
dearblue f0a64329b1 Prohibit array changes by "a"/"*" specifier of mrb_get_args()
The "a"/"*" specifier of the `mrb_get_args()` function will now return `const mrb_value *`.
This is because it is difficult for the caller to check if it is an array object and write-barrier if necessary.
And it requires calling `mrb_ary_modify()` on the unmodified array object, which is also difficult (this is similar to #5087).
2020-10-22 22:55:35 +09:00
Yukihiro "Matz" Matsumoto 55163a8a0a Rename MRB_TT_FIXNUM to MRB_TT_INTEGER.
We still have `#define MRB_TT_FIXNUM MRB_TT_INTEGER` for compatibility.
2020-10-12 16:21:47 +09:00
Yukihiro "Matz" Matsumoto 00f5ddc9ae Use mrb_funcall_id() extensively.
Except for support files e.g. `mruby-test/driver.c`, which are not
target of symbol collection via `rake gensym`.
2020-10-12 16:20:58 +09:00
Yukihiro "Matz" Matsumoto 03c2b8656b Use mrb_get_argc() to improve performance. 2020-06-25 06:57:41 +09:00
Yukihiro "Matz" Matsumoto 49ae2a69f2 Add mrb_get_arg1() that retrieves single (and only) argument.
`mrb_get_arg1()` raises `ArgumentError` if the method does not receive one
argument.

And replaces all `mrb_get_args(mrb, "o", &arg)` by the new function.
2020-06-20 12:49:46 +09:00
KOBAYASHI Shuji feaf80d899 Use type predicate macros instead of mrb_type if possible
For efficiency with `MRB_WORD_BOXING` (implement type predicate macros for
all `enum mrb_vtype`).
2019-09-26 22:23:27 +09:00
KOBAYASHI Shuji 1fd08aee15 Fix argument specs to Array 2019-06-23 20:01:33 +09:00
dearblue 56e0e1934d Name the return value of mrb_range_beg_len() 2019-05-25 12:12:21 +09:00
Yukihiro "Matz" Matsumoto 19d3bb2d90 Make #to_h to take a block; [ruby-core:89088] 2018-09-20 13:47:29 +09:00
Yukihiro "Matz" Matsumoto e9b1d9dc2f Array size may be changed in mrb_get_args() reentry.
fix #4116; fix #4117; fix #4118; fix #4119; fix #4120
2018-09-18 07:07:43 +09:00
Yukihiro "Matz" Matsumoto 3c20c96f84 Use a new function: mrb_get_argc(); ref #3826 2017-10-17 15:23:32 +09:00
Yukihiro "Matz" Matsumoto ef0b239704 Remove unnecessary inline function ary_elt.
And the function does not conform the naming convention anyway.
2017-08-11 12:57:37 +09:00
Yukihiro "Matz" Matsumoto f26d00d9e8 Embed small size array elements in the heap.
It reduces the memory consumption and sometimes improve the
performance as well.  For example, the consumed memory size
of `bench/bm_ao_render.rb` is reduced from 1.2GB to 1GB, and
its total execution time become 18.795 sec from 22.229 sec.
2017-07-27 16:13:06 +09:00
Yukihiro "Matz" Matsumoto 5d00e85314 Fixed out of bounds access; fix #3572, ref #3553 2017-04-02 20:32:11 +09:00
Yukihiro "Matz" Matsumoto 5ec051fc34 Avoid inline local variable declarations; fix #3554 2017-03-28 18:22:05 +09:00
Kenji Okimoto 33f77fe367 Implement Array#slice! 2017-03-28 15:07:57 +09:00
Yukihiro "Matz" Matsumoto 739dad6e87 Fixed a memory problem in Array#to_h
Reported from Alex Snaps via Mathieu Leduc-Hamel,
both from shopify.com.  Thank you!
2016-11-16 01:29:04 +09:00