mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	prohibi method call by defined_method in other racotrs
We can not call a non-isolated Proc in multiple ractors.
This commit is contained in:
		
							parent
							
								
									890bc2cdde
								
							
						
					
					
						commit
						caaa36b4e6
					
				
				
				Notes:
				
					git
				
				2020-09-25 20:38:03 +09:00 
				
			
			
			
		
		
					 4 changed files with 20 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -724,6 +724,17 @@ assert_equal 'can not set constants with non-shareable objects by non-main Racto
 | 
			
		|||
  end
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# define_method is not allowed
 | 
			
		||||
assert_equal "defined in a different Ractor", %q{
 | 
			
		||||
  str = "foo"
 | 
			
		||||
  define_method(:buggy){|i| str << "#{i}"}
 | 
			
		||||
  begin
 | 
			
		||||
    Ractor.new{buggy(10)}.take
 | 
			
		||||
  rescue => e
 | 
			
		||||
    e.cause.message
 | 
			
		||||
  end
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Immutable Array and Hash are shareable, so it can be shared with constants
 | 
			
		||||
assert_equal '[1000, 3]', %q{
 | 
			
		||||
  A = Array.new(1000).freeze # [nil, ...]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								method.h
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								method.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -159,6 +159,7 @@ typedef struct rb_method_refined_struct {
 | 
			
		|||
typedef struct rb_method_bmethod_struct {
 | 
			
		||||
    VALUE proc; /* should be marked */
 | 
			
		||||
    struct rb_hook_list_struct *hooks;
 | 
			
		||||
    VALUE defined_ractor;
 | 
			
		||||
} rb_method_bmethod_t;
 | 
			
		||||
 | 
			
		||||
enum method_optimized_type {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2667,9 +2667,14 @@ vm_call_bmethod_body(rb_execution_context_t *ec, struct rb_calling_info *calling
 | 
			
		|||
    rb_proc_t *proc;
 | 
			
		||||
    VALUE val;
 | 
			
		||||
    const struct rb_callcache *cc = cd->cc;
 | 
			
		||||
    const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
 | 
			
		||||
 | 
			
		||||
    if (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(vm_cc_cme(cc)->def->body.bmethod.proc, proc);
 | 
			
		||||
    GetProcPtr(cme->def->body.bmethod.proc, 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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -430,6 +430,7 @@ rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *de
 | 
			
		|||
	    }
 | 
			
		||||
	  case VM_METHOD_TYPE_BMETHOD:
 | 
			
		||||
            RB_OBJ_WRITE(me, &def->body.bmethod.proc, (VALUE)opts);
 | 
			
		||||
            RB_OBJ_WRITE(me, &def->body.bmethod.defined_ractor, GET_THREAD()->ractor->self);
 | 
			
		||||
	    return;
 | 
			
		||||
	  case VM_METHOD_TYPE_NOTIMPLEMENTED:
 | 
			
		||||
	    setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), rb_f_notimplement, -1);
 | 
			
		||||
| 
						 | 
				
			
			@ -471,6 +472,7 @@ method_definition_reset(const rb_method_entry_t *me)
 | 
			
		|||
	break;
 | 
			
		||||
      case VM_METHOD_TYPE_BMETHOD:
 | 
			
		||||
        RB_OBJ_WRITTEN(me, Qundef, def->body.bmethod.proc);
 | 
			
		||||
        RB_OBJ_WRITTEN(me, Qundef, def->body.bmethod.defined_ractor);
 | 
			
		||||
        /* give up to check all in a list */
 | 
			
		||||
        if (def->body.bmethod.hooks) rb_gc_writebarrier_remember((VALUE)me);
 | 
			
		||||
	break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue