123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138type'ahint={value:'a;loc:Wax_utils.Ast.location}typefreq=inttype'idxt={branch:boolhintoption;freq:freqhintoption;targets:('idx*int)listhintoption;}letnone={branch=None;freq=None;targets=None}(* Field by field rather than [t = none]: ['idx] is abstract here, so structural
equality on a non-empty [targets] would reach into it. *)letis_empty{branch;freq;targets}=branch=None&&freq=None&&targets=Noneletbranchlocvaluet={twithbranch=Some{value;loc}}letmap_targetsft=matcht.targetswith|None->{twithtargets=None}|Someh->{twithtargets=Some{hwithvalue=List.map(fun(x,pct)->(fx,pct))h.value};}letfreqlocvaluet={twithfreq=Some{value;loc}}lettargetslocvaluet={twithtargets=Some{value;loc}}(*** Instruction frequency ***)(* The wire byte is an offset base-2 logarithm of the executions-per-call ratio:
[f = max 1 (min 64 (floor (log2 r) + 32))], with [32] meaning once. The
endpoints are saturating, so a ratio outside \[2^-31, 2^32\] pins to 1 or 64. *)letnever_opt=0letalways_opt=127letfreq_of_ratior=ifr<=0.then1elseletl=int_of_float(Float.floor(Float.log2r))+32inmax1(min64l)(* The ratio a byte stands for, when it is one the formula can produce. [None] for
the two special values and for anything a hand-written binary put outside the
range, which have no ratio and must round-trip through the raw payload. *)letratio_of_freqb=ifb>=1&&b<=64thenSome(Float.pow2.(float_of_int(b-32)))elseNone(*** Wire payloads ***)(* A [metadata.code.instr_freq] payload is a single byte. *)letfreq_of_payloads=ifString.lengths=1thenOk(Char.codes.[0])elseError"An instruction-frequency hint must be a single byte."letfreq_payloadb=String.make1(Char.chr(bland0xff))(* [metadata.code.call_targets] holds a run of LEB128 pairs, each a function index
and a percentage. The text form spells the indices as names where it can; this
decodes the raw-byte spelling, whose indices are numeric. *)letuleb_of_stringspos=letrecgoposshiftacc=ifpos>=String.lengthsthenError"A call-target hint ends mid-integer."elseletb=Char.codes.[pos]inletacc=acclor((bland0x7f)lslshift)inifbland0x80=0thenOk(acc,pos+1)elsego(pos+1)(shift+7)accingopos00letcall_targets_of_payloads=letrecgoposacc=ifpos>=String.lengthsthenOk(List.revacc)elsematchuleb_of_stringsposwith|Error_ase->e|Ok(idx,pos)->(matchuleb_of_stringsposwith|Error_ase->e|Ok(pct,pos)->gopos((idx,pct)::acc))ingo0[]letuleb_to_bufferbn=letrecgon=letbyte=nland0x7fandrest=nlsr7inifrest=0thenBuffer.add_charb(Char.chrbyte)elsebeginBuffer.add_charb(Char.chr(bytelor0x80));gorestendingonletcall_targets_payloadl=letb=Buffer.create16inList.iter(fun(idx,pct)->uleb_to_bufferbidx;uleb_to_bufferbpct)l;Buffer.contentsb(*** Compilation priority ***)typepriority={compilation:int;optimization:intoption}(* The proposal's prose gives 127 for "run once"; its own worked example instead
renders the value as ["\01\1F"], i.e. 31. We follow the prose. The byte is only
ever a spelling of this one value, so a binary carrying 31 round-trips as the
plain number it is. *)letrun_once=127(* A [metadata.code.compilation_priority] payload is a compilation priority,
optionally followed by an optimization priority. The proposal's
forward-compatibility rule says to read the leading values and ignore the rest,
so trailing bytes are dropped rather than rejected. *)letpriority_of_payloads=matchuleb_of_strings0with|Error_->Error"A compilation-priority hint ends mid-integer."|Ok(compilation,pos)->(ifpos>=String.lengthsthenOk{compilation;optimization=None}elsematchuleb_of_stringsposwith|Error_ase->e|Ok(optimization,_)->Ok{compilation;optimization=Someoptimization})letpriority_payload{compilation;optimization}=letb=Buffer.create4inuleb_to_bufferbcompilation;Option.iter(uleb_to_bufferb)optimization;Buffer.contentsb