From 5d97bdc2dcb835c877010daa033cc2b1dfeb86d6 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Fri, 30 Oct 2020 00:32:53 +0900 Subject: Ractor.make_shareable(a_proc) Ractor.make_shareable() supports Proc object if (1) a Proc only read outer local variables (no assignments) (2) read outer local variables are shareable. Read local variables are stored in a snapshot, so after making shareable Proc, any assignments are not affeect like that: ```ruby a = 1 pr = Ractor.make_shareable(Proc.new{p a}) pr.call #=> 1 a = 2 pr.call #=> 1 # `a = 2` doesn't affect ``` [Feature #17284] --- vm_insnhelper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'vm_insnhelper.c') diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 7d4109a4c1..51b3c40010 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2688,13 +2688,15 @@ vm_call_bmethod_body(rb_execution_context_t *ec, struct rb_calling_info *calling VALUE val; const struct rb_callcache *cc = cd->cc; const rb_callable_method_entry_t *cme = vm_cc_cme(cc); + VALUE procv = cme->def->body.bmethod.proc; - if (cme->def->body.bmethod.defined_ractor != rb_ec_ractor_ptr(ec)->self) { + if (!RB_OBJ_SHAREABLE_P(procv) && + cme->def->body.bmethod.defined_ractor != rb_ec_ractor_ptr(ec)->self) { rb_raise(rb_eRuntimeError, "defined in a different Ractor"); } /* control block frame */ - GetProcPtr(cme->def->body.bmethod.proc, proc); + GetProcPtr(procv, proc); val = rb_vm_invoke_bmethod(ec, proc, calling->recv, calling->argc, argv, calling->kw_splat, calling->block_handler, vm_cc_cme(cc)); return val; -- cgit v1.2.3