123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899(**************************************************************************)(* This file is part of BINSEC. *)(* *)(* Copyright (C) 2016-2026 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* 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, version 2.1. *)(* *)(* It 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. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)openTypestype('value,'model,'state,'path,'a)field_id+=|Sibling:('value,'model,'state,'path,'pathoption)field_id|Waiting:('value,'model,'state,'path,bool)field_idtypeIr.builtin+=JoinofDba.Expr.tmodulePlugin:PLUGIN=structletname="quick-merge"letfields_=[Field{id=Sibling;default=None;copy=None;merge=None};Field{id=Waiting;default=false;copy=None;merge=None};]letextensions:typea.(moduleENGINEwithtypePath.t=a)->aextensionlist=funengine->letmoduleEngine=(valengine)inletmodulePath=Engine.Pathinletsibling=Engine.lookupSiblingandwaiting=Engine.lookupWaitinginletreleasepath=Path.setpathsiblingNone;ifPath.getpathwaitingthen(Logger.info"wake up";Path.setpathwaitingfalse;Engine.resumepathReturn)in[Builtin_printer(funppf->function|Joine->Format.fprintfppf"join if %a is symbolic"Dba_printer.Ascii.pp_expre;true|_->false);Instrumentation_routine(fungraph->Revision.iter_new_vertex(funvertex->matchRevision.nodegraphvertexwith|Fallthrough{kind=Assumeexp|Assertexp;_}|Branch{test=exp;_}|Terminator{kind=Jump{target=exp;_};_}->Revision.insert_beforegraphvertex(Builtin(Joinexp))|_->())graph);Fork_callback(funpath0path1->Option.iterrelease(Path.getpath0sibling);Path.setpath0sibling(Somepath1);Path.setpath1sibling(Somepath0));Builtin_resolver(function|Joinexp->Call(funpath0->matchPath.getpath0siblingwith|Somepath1whenPath.is_symbolicpath0exp->Path.setpath0siblingNone;ifPath.getpath1waitingthen(Path.setpath1waitingfalse;Merge([path1],Return))else(Path.setpath0waitingtrue;SignalStashed)|None|Some_->Return)|_->Unknown);Signal_callback(funpath0status->matchPath.getpath0siblingwith|Somepath1whenstatus<>Stashed||not(Path.getpath0waiting)->releasepath1|None|Some_->());]end