Files
mruby-mruby/lib/mruby
dearblue be3c0e5f4f Improve out-of-memory tolerance of mrb_env_unshare()
Exception raising can now be controlled by the caller.

The main purpose on this patch is:

- Suppress exceptions from `obj_free()` in `src/gc.c` with `mrb_env_unshare()`.

- Consider the possibility that calls to `mrb_malloc()` may cause `e` objects to be subject to GC.

  When control is returned to `mrb_env_unshare()`, `struct free_obj::next` in the same offset as `struct REnv::stack` is rewritten.
  Unexpected results then occur when the object is reused.
  Also, if `mrb_heap_page` containing an `e` object is freed, it may cause `SIGSEGV` at that point.

- Protects the value of the stack on `callinfo` that just exits if GC occurs inside `mrb_env_unshare()`.

  ```ruby
  def m
    b = -> { b }
  end

  p m.call
  # => print block object, not nil
  ```

  This patch does not raise a `NoMemoryError` exception in `mrb_env_unshare()` and can detect that error.
  Thus, the problem fixed in # 3087 is not resurrected.

Also, it may seem that this patch should suppress exceptions raised by `cipop()` during `mrb_protect_error()` and `mrb_vm_exec()` unwinds.
However, `mrb_callinfo::u.env` by `CINFO_DIRECT` is not seen to be set.
So in that case `mrb_env_unshare()` is assumed to be originally exception-free.
2022-07-30 22:32:00 +09:00
..
2021-05-31 08:25:42 +09:00
2021-08-07 16:51:04 +10:00