diff options
| author | dearblue <[email protected]> | 2020-07-18 19:05:12 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-10-12 16:21:33 +0900 |
| commit | c1f112c49a597da8478516261f0812bc073f6cd8 (patch) | |
| tree | c5f7f8d805f7bf767a06a10e9b7ef82071cfcee2 /src/gc.c | |
| parent | 0d7b4deccf445e3edae9239bf40b91cc79e83634 (diff) | |
| download | mruby-c1f112c49a597da8478516261f0812bc073f6cd8.tar.gz mruby-c1f112c49a597da8478516261f0812bc073f6cd8.zip | |
Replace global jump with catch handler implementation
When a global jump occurs, look at the catch handler table to determine where to jump.
In that case, `pc` already shows the following instruction, but since the table shows `begin_offset ... end_offset`, the comparison is done with `begin_offset < pc && pc <= end_offset`.
If there is a corresponding handler, move `pc` to `handler.target_offset` and continue running the VM.
When a global jump across `ensure` is made by `return`, `break`, `next`, `redo` and `retry`, the extended `RBreak` object saves and restores the C-level execution position.
This extended `RBreak` can have tag information, which makes it a pseudo coroutine (the "tag" mimics CRuby).
The implementation of pseudo coroutines by `RBreak` is summarized by `CHECKPOINT_RESTORE ... CHECKPOINT_MAIN ... CHECKPOINT_END` and `throw_tagged_break` / `unwind_ensure` macros.
The restart of processing is branched by `RBREAK_TAG_FOREACH(DISPATCH_CHECKPOINTS)`.
- Not only `rescue` blocks but also `ensure` blocks are now sandwiched between `OP_EXCEPT` and `OP_RAISEIF`.
- Remove the function `ecall()`.
It is no longer necessary to re-enter the VM to perform an "ensure block".
This will resolves #1888.
- Added instruction `OP_JUW` (Jump while UnWind).
It jumps unconditionally like `OP_JMP`, but searches the catch handler table and executes the ensure block.
Since it searches the catch handler table, it is much heavier than `OP_JMP`.
Diffstat (limited to 'src/gc.c')
| -rw-r--r-- | src/gc.c | 8 |
1 files changed, 0 insertions, 8 deletions
@@ -640,7 +640,6 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c) static void mark_context(mrb_state *mrb, struct mrb_context *c) { - int i; mrb_callinfo *ci; start: @@ -657,10 +656,6 @@ mark_context(mrb_state *mrb, struct mrb_context *c) mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); } } - /* mark ensure stack */ - for (i=0; i<c->eidx; i++) { - mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); - } /* mark fibers */ mrb_gc_mark(mrb, (struct RBasic*)c->fib); if (c->prev) { @@ -1014,9 +1009,6 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) if (c->stbase + i > c->stend) i = c->stend - c->stbase; children += i; - /* mark ensure stack */ - children += c->eidx; - /* mark closure */ if (c->cibase) { for (i=0, ci = c->cibase; ci <= c->ci; i++, ci++) |
