summaryrefslogtreecommitdiffhomepage
path: root/src/vm.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2015-12-31 00:11:37 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2015-12-31 00:11:37 +0900
commit3531fe179c0d58125e13dd08c53fe1ab084339c0 (patch)
tree2b0828f0080c6b95f50d3d098f8c4f00f82c373e /src/vm.c
parent4fdec33ff44a5d443014a73caaa2d30a09fb9438 (diff)
downloadmruby-3531fe179c0d58125e13dd08c53fe1ab084339c0.tar.gz
mruby-3531fe179c0d58125e13dd08c53fe1ab084339c0.zip
GC must scan env from fibers even when it's not yet copied to heap; fix #3063
Diffstat (limited to 'src/vm.c')
-rw-r--r--src/vm.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/src/vm.c b/src/vm.c
index b2149b250..58c73e4dd 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -237,22 +237,27 @@ cipush(mrb_state *mrb)
return ci;
}
+MRB_API void
+mrb_env_unshare(mrb_state *mrb, struct REnv *e)
+{
+ size_t len = (size_t)MRB_ENV_STACK_LEN(e);
+ mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
+
+ MRB_ENV_UNSHARE_STACK(e);
+ if (len > 0) {
+ stack_copy(p, e->stack, len);
+ }
+ e->stack = p;
+ mrb_write_barrier(mrb, (struct RBasic *)e);
+}
+
static void
cipop(mrb_state *mrb)
{
struct mrb_context *c = mrb->c;
if (c->ci->env) {
- struct REnv *e = c->ci->env;
- size_t len = (size_t)MRB_ENV_STACK_LEN(e);
- mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
-
- MRB_ENV_UNSHARE_STACK(e);
- if (len > 0) {
- stack_copy(p, e->stack, len);
- }
- e->stack = p;
- mrb_write_barrier(mrb, (struct RBasic *)e);
+ mrb_env_unshare(mrb, c->ci->env);
}
c->ci--;