1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283(**************************************************************************)(* *)(* OCaml *)(* *)(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 2004 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)externalmake_forward:Obj.t->Obj.t->unit="caml_obj_make_forward"typeshape=|Function|Lazy|Class|Moduleofshapearray|ValueofObj.tletoverwriteon=assert(Obj.sizeo>=Obj.sizen);fori=0toObj.sizen-1doObj.set_fieldoi(Obj.fieldni)doneletrecinit_modlocshape=matchshapewith|Function->(* Two code pointer words (curried and full application), arity
and eight environment entries makes 11 words. *)letclosure=Obj.new_blockObj.closure_tag11inlettemplate=Obj.repr(fun_->raise(Undefined_recursive_moduleloc))inoverwriteclosuretemplate;closure|Lazy->Obj.repr(lazy(raise(Undefined_recursive_moduleloc)))|Class->Obj.repr(CamlinternalOO.dummy_classloc)|Modulecomps->Obj.repr(Array.map(init_modloc)comps)|Valuev->vletrecupdate_modshapeon=matchshapewith|Function->(* In bytecode, the RESTART instruction checks the size of closures.
Hence, the optimized case [overwrite o n] is valid only if [o] and
[n] have the same size. (See PR#4008.)
In native code, the size of closures does not matter, so overwriting
is possible so long as the size of [n] is no greater than that of [o].
*)ifObj.tagn=Obj.closure_tag&&(Obj.sizen=Obj.sizeo||(Sys.backend_type=Sys.Native&&Obj.sizen<=Obj.sizeo))thenbeginoverwriteonendelseoverwriteo(Obj.repr(funx->(Obj.objn:_->_)x))|Lazy->ifObj.tagn=Obj.lazy_tagthenObj.set_fieldo0(Obj.fieldn0)elseifObj.tagn=Obj.forward_tagthenbegin(* PR#4316 *)make_forwardo(Obj.fieldn0)endelsebegin(* forwarding pointer was shortcut by GC *)make_forwardonend|Class->assert(Obj.tagn=0&&Obj.sizen=4);overwriteon|Modulecomps->assert(Obj.tagn=0&&Obj.sizen>=Array.lengthcomps);fori=0toArray.lengthcomps-1doupdate_modcomps.(i)(Obj.fieldoi)(Obj.fieldni)done|Value_->()(* the value is already there *)