123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115(**************************************************************************)(* *)(* 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)doneletoverwrite_closureon=(* We need to use the [raw_field] functions at least on the code
pointer, which is not a valid value in -no-naked-pointers
mode. *)assert(Obj.tagn=Obj.closure_tag);assert(Obj.sizeo>=Obj.sizen);letn_start_env=Obj.Closure.((infon).start_env)inleto_start_env=Obj.Closure.((infoo).start_env)in(* if the environment of n starts before the one of o,
clear the raw fields in between. *)fori=n_start_envtoo_start_env-1doObj.set_raw_fieldoiNativeint.onedone;(* if the environment of o starts before the one of n,
clear the environment fields in between. *)fori=o_start_envton_start_env-1doObj.set_fieldoi(Obj.repr())done;fori=0ton_start_env-1do(* code pointers, closure info fields, infix headers *)Obj.set_raw_fieldoi(Obj.raw_fieldni)done;fori=n_start_envtoObj.sizen-1do(* environment fields *)Obj.set_fieldoi(Obj.fieldni)done;fori=Obj.sizentoObj.sizeo-1do(* clear the leftover space *)Obj.set_fieldoi(Obj.repr())done;()letrecinit_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))inoverwrite_closureclosuretemplate;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))thenbeginoverwrite_closureonendelseoverwrite_closureo(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 *)