123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154(* Js_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
* Copyright (C) 2022 Hugo Heuzard
*
* 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!Stdlibtypet={provides:StringSet.t;requires:StringSet.t;primitives:stringlist;crcs:Digest.toptionStringMap.t;force_link:bool;effects_without_cps:bool}letempty={provides=StringSet.empty;requires=StringSet.empty;primitives=[];crcs=StringMap.empty;force_link=false;effects_without_cps=false}letof_primitivesl={provides=StringSet.empty;requires=StringSet.empty;primitives=l;crcs=StringMap.empty;force_link=true;effects_without_cps=false}letof_cmo(cmo:Cmo_format.compilation_unit)=letopenOcaml_compilerin(* A packed librariy register global for packed modules. *)letprovides=StringSet.of_list(Cmo_format.namecmo::Cmo_format.providescmo)inletrequires=StringSet.of_list(Cmo_format.requirescmo)inletrequires=StringSet.diffrequiresprovidesinleteffects_without_cps=(matchConfig.effects()with|`Disabled|`Jspi->true|`Cps|`Double_translation->false)&&List.exists(Cmo_format.primitivescmo)~f:(function|"%resume"|"%reperform"|"%perform"->true|_->false)inletforce_link=Cmo_format.force_linkcmoinletcrcs=List.fold_left(Cmo_format.importscmo)~init:StringMap.empty~f:(funacc(s,o)->StringMap.addsoacc)in{provides;requires;primitives=[];force_link;effects_without_cps;crcs}letuniont1t2=letprovides=StringSet.uniont1.providest2.providesinletrequires=StringSet.uniont1.requirest2.requiresinletrequires=StringSet.diffrequiresprovidesinletprimitives=t1.primitives@t2.primitivesinletcrcs=StringMap.merge(fun_v1v2->matchv1,v2with|None,x->x|x,None->x|SomeNone,Somex->Somex|Somex,SomeNone->Somex|Some(Somex),Some(Somey)->ifString.equalxythenSome(Somex)elsefailwith(Printf.sprintf"Inconsistent assumption blah.."))t1.crcst2.crcsin{provides;requires;primitives;force_link=t1.force_link||t2.force_link;effects_without_cps=t1.effects_without_cps||t2.effects_without_cps;crcs}letprefix="//# unitInfo:"letto_stringt=[[prefix;"Provides:";String.concat~sep:", "(StringSet.elementst.provides)];(ifStringSet.equalempty.requirest.requiresthen[]else[prefix;"Requires:";String.concat~sep:", "(StringSet.elementst.requires)]);(ifList.equal~eq:String.equalempty.primitivest.primitivesthen[]else[prefix;"Primitives:";String.concat~sep:", "t.primitives]);(ifBool.equalempty.force_linkt.force_linkthen[]else[prefix;"Force_link:";string_of_boolt.force_link]);(ifBool.equalempty.effects_without_cpst.effects_without_cpsthen[]else[prefix;"Effects_without_cps:";string_of_boolt.effects_without_cps])]|>List.filter_map~f:(function|[]->None|l->Some(String.concat~sep:" "l))|>String.concat~sep:"\n"|>funx->x^"\n"letparse_stringlists=String.split_on_char~sep:','s|>List.filter_map~f:(funs->matchString.trimswith|""->None|s->Somes)letparse_stringsets=parse_stringlists|>StringSet.of_listletparseaccs=matchString.drop_prefix~prefixswith|None->None|Somesuffix->(letsuffix=String.trimsuffixinmatchString.lsplit2~on:':'suffixwith|None->None|Some("Provides",provides)->Some{accwithprovides=StringSet.unionacc.provides(parse_stringsetprovides)}|Some("Requires",requires)->Some{accwithrequires=StringSet.unionacc.requires(parse_stringsetrequires)}|Some("Primitives",primitives)->Some{accwithprimitives=acc.primitives@parse_stringlistprimitives}|Some("Force_link",flink)->Some{accwithforce_link=bool_of_string(String.trimflink)||acc.force_link}|Some("Effects_without_cps",b)->Some{accwitheffects_without_cps=bool_of_string(String.trimb)}|Some(_,_)->None)