CAMLprim value caml_weak_blit (value ars, value ofs, value ard, value ofd, value len) { mlsize_t offset_s = Long_val (ofs) + 1; mlsize_t offset_d = Long_val (ofd) + 1; mlsize_t length = Long_val (len); long i; Assert (Is_in_heap (ars)); Assert (Is_in_heap (ard)); if (offset_s < 1 || offset_s + length > Wosize_val (ars)){ caml_invalid_argument ("Weak.blit"); } if (offset_d < 1 || offset_d + length > Wosize_val (ard)){ caml_invalid_argument ("Weak.blit"); } if (caml_gc_phase == Phase_mark && caml_gc_subphase == Subphase_weak1){ for (i = 0; i < length; i++){ value v = Field (ars, offset_s + i); if (v != caml_weak_none && Is_block (v) && Is_in_heap (v) && Is_white_val (v)){ Field (ars, offset_s + i) = caml_weak_none; } } } if (offset_d < offset_s){ for (i = 0; i < length; i++){ do_set (ard, offset_d + i, Field (ars, offset_s + i)); } }else{ for (i = length - 1; i >= 0; i--){ do_set (ard, offset_d + i, Field (ars, offset_s + i)); } } return Val_unit; }
static int isdead(value v) { return v == ((value) NULL) || (gc_phase == Phase_weak && IS_BLOCK(v) && Is_in_heap(v) && Is_white_val(v)); }