`string[]=(idx, replace)` should return `replace`.
## Actual (wrong)
```
string.[]=(idx, replace) → string
string.[]=(idx, len, replace) → string
```
## Expected
```
string.[]=(idx, replace) → replace
string.[]=(idx, len, replace) → replace
```
## Sidenote
As of the current mruby-compiler, `(string[idx] = 'X')` creates not only "CALL_NODE" but also "ASGN_NODE" and "OP_MOVE", overriding the wrong return value.
On the other hand, `string.[]=(idx, 'X')` creates only "CALL_NODE", exposing the wrong return value.
If my new mruby-compiler2, leveraging Prism, took the place of official compiler, `(string[idx] = 'X')` and `string.[]=(idx, 'X')` would be going to generate the same VM code without "OP_MOVE".
So I paranoidly added tests.
FYI: You can find how the new mruby-compiler2's AST and VM code look like in mruby/c's issue (mruby/c had the same bug): https://github.com/mrubyc/mrubyc/pull/210
This reverts commit ad2e626e7a.
Because of the changes made by #6282, the following code caused a problem.
```ruby
b = proc { break "BAD!" }
p self.tap { b.call }
# (expected) => break from proc-closure (LocalJumpError)
# (after #6282) => "BAD!"
```
I revived the `mrb_callinfo::blk` field to fix this, but it did not overcome the following problem.
```ruby
def m(&b); b = b.clone; GC.start; b.call; end
p m { break "OK!" }
# (expected) => "OK!"
# (revived blk) => break from proc-closure (LocalJumpError)
```
By adding a fast-path where we ignore boxed types we can gain a pretty substantial speedup of mrb_iv_get, making it about 25% faster during a standard optcarrot benchmark run.
NOTE: It is just mrb_iv_get that is that much faster, the whole benchmark seems to be about 3-5% faster with word boxing.
- use heap sort (O(1)) instead of merge sort (O(n)) for better space
complexity.
- method implemented in C for better performance
As a result, simple sorting now consumes far less memory and is faster.
Since it's implemented in C, fiber context switching is not allowed from
comparison, but we consider the risk is minimal (no one switches context
in the comparison, right?)
- There was some unnecessary complexity in `OP_BREAK` introduced in commit ad2e626 (#6282).
- Since `mrb->c` is never NULL, there is no need to check it with `MRB_ENV_ONSTACK_P()` beforehand.
Supplement to commit 177debacc5 (#6276).
If the ci is incomplete, the previous method may cause the application to crash because `env->stack` points to an invalid address when expanding the data stack.
Since the ci is in an abnormal state, control it by putting `NULL` in `env->stack`.
If the ci is fine and top-level, detach `env` as usual with `mrb_env_unshare()`.
The part removed in this patch was introduced by commit c7c9543bed.
The current mechanism should be able to trace from block objects created by `eval` to higher level blocks without any problems.
There are two issues to be fixed:
- `mrb_irep` could leak if `mrb_calloc()` encountered an out-of-memory exception
- `mrb_proc_merge_lvar()` allocated one extra variable name.
`irep->lv` can always refer to only one less range than `irep->nlocals`.
Also, when `mrb_proc_merge_lvar()` extends `irep->lv`, `mrb_realloc()` with `NULL` has the same behavior as `mrb_malloc()`.
Set `env->cxt` to `NULL` when it is detached from the call frame.
In other words, we can determine if `env->cxt` is `NULL` or not.
Also, `mruby-binding` had been setting `env->cxt` unnecessarily, so this has been fixed.
We need to include stdlib.h and malloc.h to use malloc()/free() but
they aren't included in src/string.c with WIN32_LEAN_AND_MEAN. It
generates build time warnings.
We can solve this by including stdlib.h and malloc.h explicitly.
In the following example, the fiber context and call stack may be in an incomplete state.
- In case another thread running mruby is terminated abnormally
- In case of a global jump that is out of management by mruby