The s = self workaround and XXX comment in recvfrom_nonblock date back
to the initial import of mruby-socket. The underlying bug where self
became a SystemcallException inside ensure blocks has since been fixed.
Verified that self correctly refers to the socket object in ensure
blocks after exceptions from recvfrom.
This patch fixes a bug in the stack extension logic that could cause a HardFault on certain configurations when the stack is reallocated to a new address.
## Background
When the mruby VM's stack runs out, stack_extend_alloc() calls mrb_realloc to grow it.
If reallocation moves the block to a new address, envadjust() adjusts all ci->stack pointers to point into the new allocation.
## The bug
The bug happened under the configuration below:
- MRB_INT64 on MRB_32BIT (`sizeof(mrb_value) == 16` because MRB_NO_BOXING is now mandatory)
- Allocator with 8-byte alignment (eg. PICORB_ALLOC_ALIGN=8 in PicoRuby for Raspi Pico)
The delta was computed via mrb_value* pointer subtraction:
```c
ptrdiff_t delta = newbase - oldbase; // units of sizeof(mrb_value)
```
If :
- Old address: 0x2004c508
- New address: 0x2004c510 (8-byte difference)
The pointer subtraction truncated: 8 / 16 = 0.
envadjust() was misleaded as `delta == 0` and returned early without adjusting any ci->stack pointers.
The stbase was updated to the new address, but all stack pointers still pointed 8 bytes before it.
Every register access was shifted, reading garbage, ultimately causing a HardFault.
## The fix
Byte-level char* calculation instead of mrb_value* calculation:
```c
ptrdiff_t off = (char*)newbase - (char*)oldbase;
// ...
ci->stack = (mrb_value*)((char*)ci->stack + off);
```
This ensures the adjustment is exact regardless of sizeof(mrb_value) and allocator alignment.
Change the grammar rule for tLPAREN_ARG from accepting only a
single stmt to accepting compstmt. This allows compound
statements with semicolons inside parenthesized arguments when
the parenthesis is preceded by a space, e.g., `p (f1; f2)`.
This matches the behavior of CRuby 3.3+.
Fixes#6766.
Co-authored-by: Claude <noreply@anthropic.com>
When the block passed to Lazy#flat_map returns a non-enumerable value
(e.g. an Integer), mruby raised NoMethodError because it unconditionally
called #each on the result. CRuby yields non-enumerable values directly.
Use respond_to?(:each) to match CRuby behavior: iterate enumerable
results, yield non-enumerable results as-is.
With `rake -m`, the C compiler can start reading a partially-written
gem_test.c before generation completes. Write to a .tmp file first,
then rename to the final path.
Co-authored-by: Claude <noreply@anthropic.com>
Previously only the first match was removed, leaking duplicate
entries when the same object was registered multiple times.
Use two-pointer compaction for O(N) removal.
Fixes#6760.
Co-authored-by: Claude <noreply@anthropic.com>
There are two reasons:
- If the mruby call stack is extended, the `ci` variable may become invalid.
- The C language does not specify the order in which the left-hand and right-hand sides of an assignment expression are evaluated.
Therefore, if the mruby data stack is extended, `ci->stack` may become invalid.
Several methods defined in mruby-array-ext are written in C and may call `mrb_vm_exec()`.
If array objects are modified on the Ruby side, problems may arise in subsequent processing.
- Using objects that have been removed from the array and garbage collected
- Using pointers or array lengths that have become invalid due to changes to the array object
- Modifying the contents of a shared array object directly
ref: https://github.com/mruby/mruby/issues/6662
`mrb_hash_delete` returns the removed element (which is guaranteed to
exist due to the `mrb_hash_key_p` check), this prevents the hash from
being searched twice.
Replace `__product_group` method with `__product_generate` and `__product_next`.
This change eliminates the need for Ruby to perform internal state calculations, allowing it to simply receive the results.
attr_reader-generated getter methods silently ignored any arguments
passed to them. CRuby raises ArgumentError in this case.
Add mrb_get_args(mrb, "") to enforce zero arguments, matching CRuby.
Commit 250bf6edd renamed KHASH_DEFAULT_SIZE to KHASH_INITIAL_SIZE but
missed updating build_config files and documentation. Also restore the
default value in khash.h to 32, consistent with the documented default
and the profile hierarchy (MRB_CONSTRAINED_BASELINE_PROFILE reduces it
to 16).