123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116(* Js_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
* Copyright (C) 2010 Jérôme Vouillon
* Laboratoire PPS - CNRS Université Paris Diderot
*
* 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!StdlibopenCodeletsubst_conts(pc,arg)=pc,List.maparg~f:(funx->sx)letexprse=matchewith|Constant_->e|Apply(f,l,n)->Apply(sf,List.mapl~f:(funx->sx),n)|Block(n,a,k)->Block(n,Array.mapa~f:(funx->sx),k)|Field(x,n)->Field(sx,n)|Closure(l,pc)->Closure(l,subst_contspc)|Prim(p,l)->Prim(p,List.mapl~f:(funx->matchxwith|Pvx->Pv(sx)|Pc_->x))letinstrsi=matchiwith|Let(x,e)->Let(x,exprse)|Set_field(x,n,y)->Set_field(sx,n,sy)|Offset_ref(x,n)->Offset_ref(sx,n)|Array_set(x,y,z)->Array_set(sx,sy,sz)letinstrssl=List.mapl~f:(funi->instrsi)letlastsl=matchlwith|Stop->l|Branchcont->Branch(subst_contscont)|Pushtrap(cont1,x,cont2,pcs)->Pushtrap(subst_contscont1,x,subst_contscont2,pcs)|Returnx->Return(sx)|Raise(x,k)->Raise(sx,k)|Cond(x,cont1,cont2)->Cond(sx,subst_contscont1,subst_contscont2)|Switch(x,a1,a2)->Switch(sx,Array.mapa1~f:(funcont->subst_contscont),Array.mapa2~f:(funcont->subst_contscont))|Poptrap(cont,addr)->Poptrap(subst_contscont,addr)letblocksblock={params=block.params;handler=Option.mapblock.handler~f:(fun(x,cont)->x,subst_contscont);body=instrssblock.body;branch=lastsblock.branch}letprogramsp=letblocks=Addr.Map.map(funb->blocksb)p.blocksin{pwithblocks}letreccont'spcblocksvisited=ifAddr.Set.mempcvisitedthenblocks,visitedelseletvisited=Addr.Set.addpcvisitedinletb=Addr.Map.findpcblocksinletb=blocksbinletblocks=Addr.Map.addpcbblocksinletblocks,visited=List.fold_leftb.body~init:(blocks,visited)~f:(fun(blocks,visited)instr->matchinstrwith|Let(_,Closure(_,(pc,_)))->cont'spcblocksvisited|_->blocks,visited)inCode.fold_childrenblockspc(funpc(blocks,visited)->cont'spcblocksvisited)(blocks,visited)letcontsaddrp=letblocks,_=cont'saddrp.blocksAddr.Set.emptyin{pwithblocks}(****)letfrom_arraysx=matchs.(Var.idxx)with|Somey->y|None->x(****)letrecbuild_mappingparamsargs=matchparams,argswith|x::params,y::args->Var.Map.addxy(build_mappingparamsargs)|[],[]->Var.Map.empty|_->assertfalseletfrom_mapmx=tryVar.Map.findxmwithNot_found->x