123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255(* Js_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)open!Stdlibletrecconstant_of_constc:Code.constant=letopenLambdainletopenAsttypesinmatchcwith|Const_base(Const_inti)->Int(Targetint.of_int_warning_on_overflowi)|Const_base(Const_charc)->Int(Targetint.of_int_exn(Char.codec))|((Const_base(Const_string(s,_)))[@ifocaml_version<(4,11,0)])|((Const_base(Const_string(s,_,_)))[@ifocaml_version>=(4,11,0)])->Strings|Const_base(Const_floats)->Float(float_of_strings)|Const_base(Const_int32i)->(matchConfig.target()with|`JavaScript->Int(Targetint.of_int32_warning_on_overflowi)|`Wasm->Int32i)|Const_base(Const_int64i)->Int64i|Const_base(Const_nativeinti)->(matchConfig.target()with|`JavaScript->Int(Targetint.of_nativeint_warning_on_overflowi)|`Wasm->NativeInt(Int32.of_nativeint_warning_on_overflowi))|Const_immstrings->Strings|Const_float_arraysl->letl=List.map~f:(funf->float_of_stringf)slinFloat_array(Array.of_listl)|((Const_pointeri)[@ifocaml_version<(4,12,0)])->Int(Targetint.of_int_warning_on_overflowi)|Const_block(tag,l)->letl=Array.of_list(List.mapl~f:constant_of_const)inTuple(tag,l,Unknown)moduleSymtable=struct(* Copied from ocaml/bytecomp/symtable.ml *)moduleNum_tbl(M:Map.S)=struct[@@@ocaml.warning"-32"]typet={cnt:int;(* The next number *)tbl:intM.t(* The table of already numbered objects *)}letempty={cnt=0;tbl=M.empty}letfindkeynt=M.findkeynt.tblletiterfnt=M.iterfnt.tblletfoldfnta=M.foldfnt.tblaletenterntkey=letn=!nt.cntinnt:={cnt=n+1;tbl=M.addkeyn!nt.tbl};nletincrnt=letn=!nt.cntinnt:={cnt=n+1;tbl=!nt.tbl};nendmoduleGlobal=structtypet=|Glob_compunitofstring|Glob_predefofstringletname=function|Glob_compunitcu->cu|Glob_predefexn->exnletof_identid=letname=Ident.nameidinifIdent.is_predefidthenSome(Glob_predefname)elseifIdent.globalidthenSome(Glob_compunitname)elseNoneletto_ident=function|Glob_compunitx->Ident.create_persistentx|Glob_predefx->Ident.create_predefx[@@ocaml.warning"-32"]endmoduleGlobalMap=structmoduleGlobalMap=Num_tbl(Ident.Map)includeGlobalMapletto_localx=matchGlobal.of_identxwith|None->assertfalse|Somex->xletof_local=Global.to_identletfilter(p:Global.t->bool)(gmap:t)=letnewtbl=refIdent.Map.emptyinIdent.Map.iter(funidnum->ifp(to_localid)thennewtbl:=Ident.Map.addidnum!newtbl)gmap.tbl;{cnt=gmap.cnt;tbl=!newtbl}letfindidt=find(of_localid)tletiter~ft=iter(funidpos->f(to_localid)pos)tletfoldftacc=fold(funidacc->f(to_localid)acc)taccletentertid=entert(of_localid)end[@@ifocaml_version<(5,2,0)]moduleGlobalMap=structmoduleGlobalMap=Num_tbl(Symtable.Global.Map)includeGlobalMapletto_local=function|Symtable.Global.Glob_compunit(Compunitx)->Global.Glob_compunitx|Symtable.Global.Glob_predef(Predef_exnx)->Global.Glob_predefxletof_local=function|Global.Glob_compunitx->Symtable.Global.Glob_compunit(Compunitx)|Global.Glob_predefx->Symtable.Global.Glob_predef(Predef_exnx)letfilter(p:Global.t->bool)(gmap:t)=letnewtbl=refSymtable.Global.Map.emptyinSymtable.Global.Map.iter(funidnum->ifp(to_localid)thennewtbl:=Symtable.Global.Map.addidnum!newtbl)gmap.tbl;{cnt=gmap.cnt;tbl=!newtbl}letfindidt=find(of_localid)tletiter~ft=iter(funidpos->f(to_localid)pos)tletfoldftacc=fold(funidacc->f(to_localid)acc)taccletentertid=entert(of_localid)end[@@ifocaml_version>=(5,2,0)]letreloc_get_of_stringname=Cmo_format.Reloc_getglobal(Ident.create_persistentname)[@@ifocaml_version<(5,2,0)]letreloc_set_of_stringname=Cmo_format.Reloc_setglobal(Ident.create_persistentname)[@@ifocaml_version<(5,2,0)]letreloc_get_of_stringname=Cmo_format.Reloc_getcompunit(Compunitname)[@@ifocaml_version>=(5,2,0)]letreloc_set_of_stringname=Cmo_format.Reloc_setcompunit(Compunitname)[@@ifocaml_version>=(5,2,0)]letreloc_identname=letbuf=Bytes.create4inlet()=trySymtable.patch_object[|buf|][reloc_get_of_stringname,0]with_->Symtable.patch_object[|buf|][reloc_set_of_stringname,0]inletgeti=Char.code(Bytes.getbufi)inletn=get0+(get1lsl8)+(get2lsl16)+(get3lsl24)inn[@@ifocaml_version<(5,2,0)]letreloc_identname=letbuf=Bigarray.(Array1.createcharc_layout4)inlet()=trySymtable.patch_objectbuf[reloc_get_of_stringname,0]with_->Symtable.patch_objectbuf[reloc_set_of_stringname,0]inletgeti=Char.code(Bigarray.Array1.getbufi)inletn=get0+(get1lsl8)+(get2lsl16)+(get3lsl24)inn[@@ifocaml_version>=(5,2,0)]letcurrent_state():GlobalMap.t=letx:Symtable.global_map=Symtable.current_state()inObj.magicxletall_primitives():stringlist=letsplit_primitivesp=letlen=String.lengthpinletrecsplitbegcur=ifcur>=lenthen[]elseifChar.equalp.[cur]'\000'thenString.subp~pos:beg~len:(cur-beg)::split(cur+1)(cur+1)elsesplitbeg(cur+1)insplit00insplit_primitives(Symtable.data_primitive_names())[@@ifocaml_version<(5,2)]letall_primitives():stringlist=Symtable.data_primitive_names()[@@ifocaml_version>=(5,2)]endmoduleCmo_format=structtypet=Cmo_format.compilation_unitletname(t:t)=t.cu_name[@@ifocaml_version<(5,2,0)]letname(t:t)=let(Compunitname)=t.cu_nameinname[@@ifocaml_version>=(5,2,0)]letrequires(t:t)=List.map~f:Ident.namet.cu_required_globals[@@ifocaml_version<(5,2,0)]letrequires(t:t)=List.mapt.cu_required_compunits~f:(fun(Compunitu)->u)[@@ifocaml_version>=(5,2,0)]letprovides(t:t)=List.filter_mapt.cu_reloc~f:(fun((reloc:Cmo_format.reloc_info),_)->matchrelocwith|Reloc_setglobali->Some(Ident.namei)|Reloc_getglobal_|Reloc_literal_|Reloc_primitive_->None)[@@ifocaml_version<(5,2,0)]letprovides(t:t)=List.filter_mapt.cu_reloc~f:(fun((reloc:Cmo_format.reloc_info),_)->matchrelocwith|Reloc_setcompunit(Compunitu)->Someu|Reloc_getcompunit_|Reloc_getpredef_|Reloc_literal_|Reloc_primitive_->None)[@@ifocaml_version>=(5,2,0)]letprimitives(t:t)=t.cu_primitivesletimports(t:t)=t.cu_importsletforce_link(t:t)=t.cu_force_linkend