interp.ml 151 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094
  1. (*
  2. * Copyright (C)2005-2013 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. *)
  22. open Common
  23. open Nast
  24. open Unix
  25. open Type
  26. (* ---------------------------------------------------------------------- *)
  27. (* TYPES *)
  28. type value =
  29. | VNull
  30. | VBool of bool
  31. | VInt of int
  32. | VFloat of float
  33. | VString of string
  34. | VObject of vobject
  35. | VArray of value array
  36. | VAbstract of vabstract
  37. | VFunction of vfunction
  38. | VClosure of value list * (value list -> value list -> value)
  39. | VInt32 of int32
  40. and vobject = {
  41. mutable ofields : (int * value) array;
  42. mutable oproto : vobject option;
  43. }
  44. and vabstract =
  45. | ADeallocated of int ref
  46. | AKind of vabstract
  47. | AHash of (value, value) Hashtbl.t
  48. | ARandom of Random.State.t ref
  49. | ABuffer of Buffer.t
  50. | APos of Ast.pos
  51. | AFRead of (in_channel * bool ref)
  52. | AFWrite of out_channel
  53. | AReg of regexp
  54. | AZipI of zlib
  55. | AZipD of zlib
  56. | AUtf8 of UTF8.Buf.buf
  57. | ASocket of Unix.file_descr
  58. | ATDecl of module_type
  59. | AUnsafe of Obj.t
  60. | ALazyType of (unit -> Type.t) ref
  61. | ANekoAbstract of Extc.value
  62. | ANekoBuffer of value
  63. | ACacheRef of value
  64. | AInt32Kind
  65. | ATls of value ref
  66. | AProcess of Process.process
  67. and vfunction =
  68. | Fun0 of (unit -> value)
  69. | Fun1 of (value -> value)
  70. | Fun2 of (value -> value -> value)
  71. | Fun3 of (value -> value -> value -> value)
  72. | Fun4 of (value -> value -> value -> value -> value)
  73. | Fun5 of (value -> value -> value -> value -> value -> value)
  74. | FunVar of (value list -> value)
  75. and regexp = {
  76. r : Str.regexp;
  77. mutable r_string : string;
  78. mutable r_groups : (int * int) option array;
  79. }
  80. and zlib = {
  81. z : Extc.zstream;
  82. mutable z_flush : Extc.zflush;
  83. }
  84. type cmp =
  85. | CEq
  86. | CSup
  87. | CInf
  88. | CUndef
  89. type extern_api = {
  90. pos : Ast.pos;
  91. get_com : unit -> Common.context;
  92. get_type : string -> Type.t option;
  93. get_module : string -> Type.t list;
  94. on_generate : (Type.t list -> unit) -> unit;
  95. after_generate : (unit -> unit) -> unit;
  96. on_type_not_found : (string -> value) -> unit;
  97. parse_string : string -> Ast.pos -> bool -> Ast.expr;
  98. type_expr : Ast.expr -> Type.texpr;
  99. store_typed_expr : Type.texpr -> Ast.expr;
  100. get_display : string -> string;
  101. allow_package : string -> unit;
  102. type_patch : string -> string -> bool -> string option -> unit;
  103. meta_patch : string -> string -> string option -> bool -> unit;
  104. set_js_generator : (value -> unit) -> unit;
  105. get_local_type : unit -> t option;
  106. get_expected_type : unit -> t option;
  107. get_call_arguments : unit -> Ast.expr list option;
  108. get_local_method : unit -> string;
  109. get_local_using : unit -> tclass list;
  110. get_local_vars : unit -> (string, Type.tvar) PMap.t;
  111. get_build_fields : unit -> value;
  112. get_pattern_locals : Ast.expr -> Type.t -> (string,Type.tvar * Ast.pos) PMap.t;
  113. define_type : value -> unit;
  114. define_module : string -> value list -> ((string * Ast.pos) list * Ast.import_mode) list -> Ast.type_path list -> unit;
  115. module_dependency : string -> string -> bool -> unit;
  116. current_module : unit -> module_def;
  117. delayed_macro : int -> (unit -> (unit -> value));
  118. use_cache : unit -> bool;
  119. format_string : string -> Ast.pos -> Ast.expr;
  120. cast_or_unify : Type.t -> texpr -> Ast.pos -> Type.texpr;
  121. add_global_metadata : string -> string -> (bool * bool * bool) -> unit;
  122. }
  123. type callstack = {
  124. cpos : pos;
  125. cthis : value;
  126. cstack : int;
  127. cenv : value array;
  128. }
  129. type context = {
  130. gen : Genneko.context;
  131. types : (Type.path,int) Hashtbl.t;
  132. prototypes : (string list, vobject) Hashtbl.t;
  133. fields_cache : (int,string) Hashtbl.t;
  134. mutable error : bool;
  135. mutable error_proto : vobject;
  136. mutable enums : (value * string) array array;
  137. mutable do_call : value -> value -> value list -> pos -> value;
  138. mutable do_string : value -> string;
  139. mutable do_loadprim : value -> value -> value;
  140. mutable do_compare : value -> value -> cmp;
  141. mutable loader : value;
  142. mutable exports : value;
  143. (* runtime *)
  144. mutable stack : value DynArray.t;
  145. mutable callstack : callstack list;
  146. mutable callsize : int;
  147. mutable exc : pos list;
  148. mutable vthis : value;
  149. mutable venv : value array;
  150. (* context *)
  151. mutable curapi : extern_api;
  152. mutable on_reused : (unit -> bool) list;
  153. mutable is_reused : bool;
  154. (* eval *)
  155. mutable locals_map : (string, int) PMap.t;
  156. mutable locals_count : int;
  157. mutable locals_barrier : int;
  158. mutable locals_env : string DynArray.t;
  159. mutable globals : (string, value ref) PMap.t;
  160. }
  161. type access =
  162. | AccThis
  163. | AccLocal of int
  164. | AccGlobal of value ref
  165. | AccEnv of int
  166. | AccField of (unit -> value) * string
  167. | AccArray of (unit -> value) * (unit -> value)
  168. exception Runtime of value
  169. exception Builtin_error
  170. exception Error of string * Ast.pos list
  171. exception Abort
  172. exception Continue
  173. exception Break of value
  174. exception Return of value
  175. exception Invalid_expr
  176. exception Sys_exit of int
  177. (* ---------------------------------------------------------------------- *)
  178. (* UTILS *)
  179. let get_ctx_ref = ref (fun() -> assert false)
  180. let encode_complex_type_ref = ref (fun t -> assert false)
  181. let encode_type_ref = ref (fun t -> assert false)
  182. let decode_type_ref = ref (fun t -> assert false)
  183. let encode_expr_ref = ref (fun e -> assert false)
  184. let decode_expr_ref = ref (fun e -> assert false)
  185. let encode_texpr_ref = ref (fun e -> assert false)
  186. let decode_texpr_ref = ref (fun e -> assert false)
  187. let encode_clref_ref = ref (fun c -> assert false)
  188. let enc_hash_ref = ref (fun h -> assert false)
  189. let enc_array_ref = ref (fun l -> assert false)
  190. let dec_array_ref = ref (fun v -> assert false)
  191. let enc_string_ref = ref (fun s -> assert false)
  192. let make_ast_ref = ref (fun _ -> assert false)
  193. let make_complex_type_ref = ref (fun _ -> assert false)
  194. let encode_tvar_ref = ref (fun _ -> assert false)
  195. let decode_path_ref = ref (fun _ -> assert false)
  196. let decode_import_ref = ref (fun _ -> assert false)
  197. let get_ctx() = (!get_ctx_ref)()
  198. let enc_array (l:value list) : value = (!enc_array_ref) l
  199. let dec_array (l:value) : value list = (!dec_array_ref) l
  200. let encode_complex_type (t:Ast.complex_type) : value = (!encode_complex_type_ref) t
  201. let encode_type (t:Type.t) : value = (!encode_type_ref) t
  202. let decode_type (v:value) : Type.t = (!decode_type_ref) v
  203. let encode_expr (e:Ast.expr) : value = (!encode_expr_ref) e
  204. let decode_expr (e:value) : Ast.expr = (!decode_expr_ref) e
  205. let encode_texpr (e:Type.texpr) : value = (!encode_texpr_ref) e
  206. let decode_texpr (v:value) : Type.texpr = (!decode_texpr_ref) v
  207. let encode_clref (c:tclass) : value = (!encode_clref_ref) c
  208. let enc_hash (h:('a,'b) Hashtbl.t) : value = (!enc_hash_ref) h
  209. let make_ast (e:texpr) : Ast.expr = (!make_ast_ref) e
  210. let enc_string (s:string) : value = (!enc_string_ref) s
  211. let make_complex_type (t:Type.t) : Ast.complex_type = (!make_complex_type_ref) t
  212. let encode_tvar (v:tvar) : value = (!encode_tvar_ref) v
  213. let decode_path (v:value) : Ast.type_path = (!decode_path_ref) v
  214. let decode_import (v:value) : ((string * Ast.pos) list * Ast.import_mode) = (!decode_import_ref) v
  215. let to_int f = Int32.of_float (mod_float f 2147483648.0)
  216. let need_32_bits i = Int32.compare (Int32.logand (Int32.add i 0x40000000l) 0x80000000l) Int32.zero <> 0
  217. let best_int i = if need_32_bits i then VInt32 i else VInt (Int32.to_int i)
  218. let make_pos p =
  219. let low = p.pline land 0xFFFFF in
  220. {
  221. Ast.pfile = p.psource;
  222. Ast.pmin = low;
  223. Ast.pmax = low + (p.pline lsr 20);
  224. }
  225. let warn ctx msg p =
  226. (ctx.curapi.get_com()).Common.warning msg (make_pos p)
  227. let rec pop ctx n =
  228. if n > 0 then begin
  229. DynArray.delete_last ctx.stack;
  230. pop ctx (n - 1);
  231. end
  232. let pop_ret ctx f n =
  233. let v = f() in
  234. pop ctx n;
  235. v
  236. let push ctx v =
  237. DynArray.add ctx.stack v
  238. let hash f =
  239. let h = ref 0 in
  240. for i = 0 to String.length f - 1 do
  241. h := !h * 223 + int_of_char (String.unsafe_get f i);
  242. done;
  243. if Sys.word_size = 64 then Int32.to_int (Int32.shift_right (Int32.shift_left (Int32.of_int !h) 1) 1) else !h
  244. let constants =
  245. let h = Hashtbl.create 0 in
  246. List.iter (fun f -> Hashtbl.add h (hash f) f)
  247. ["done";"read";"write";"min";"max";"file";"args";"loadprim";"loadmodule";"__a";"__s";"h";
  248. "tag";"index";"length";"message";"pack";"name";"params";"sub";"doc";"kind";"meta";"access";
  249. "constraints";"opt";"type";"value";"ret";"expr";"field";"values";"get";"__string";"toString";
  250. "$";"add";"remove";"has";"__t";"module";"isPrivate";"isPublic";"isExtern";"isInterface";"exclude";
  251. "constructs";"names";"superClass";"interfaces";"fields";"statics";"constructor";"init";"t";
  252. "gid";"uid";"atime";"mtime";"ctime";"dev";"ino";"nlink";"rdev";"size";"mode";"pos";"len";
  253. "binops";"unops";"from";"to";"array";"op";"isPostfix";"impl";
  254. "id";"capture";"extra";"v";"ids";"vars";"en";"overrides";"status"];
  255. h
  256. let h_get = hash "__get" and h_set = hash "__set"
  257. and h_add = hash "__add" and h_radd = hash "__radd"
  258. and h_sub = hash "__sub" and h_rsub = hash "__rsub"
  259. and h_mult = hash "__mult" and h_rmult = hash "__rmult"
  260. and h_div = hash "__div" and h_rdiv = hash "__rdiv"
  261. and h_mod = hash "__mod" and h_rmod = hash "__rmod"
  262. and h_string = hash "__string" and h_compare = hash "__compare"
  263. and h_constructs = hash "__constructs__" and h_a = hash "__a" and h_s = hash "__s"
  264. and h_class = hash "__class__"
  265. let exc v =
  266. raise (Runtime v)
  267. let hash_field ctx f =
  268. let h = hash f in
  269. (try
  270. let f2 = Hashtbl.find ctx.fields_cache h in
  271. if f <> f2 then exc (VString ("Field conflict between " ^ f ^ " and " ^ f2));
  272. with Not_found ->
  273. Hashtbl.add ctx.fields_cache h f);
  274. h
  275. let field_name ctx fid =
  276. try
  277. Hashtbl.find ctx.fields_cache fid
  278. with Not_found ->
  279. "???"
  280. let obj hash fields =
  281. let fields = Array.of_list (List.map (fun (k,v) -> hash k, v) fields) in
  282. Array.sort (fun (k1,_) (k2,_) -> compare k1 k2) fields;
  283. {
  284. ofields = fields;
  285. oproto = None;
  286. }
  287. let parse_int s =
  288. let rec loop_hex i =
  289. if i = String.length s then s else
  290. match String.unsafe_get s i with
  291. | '0'..'9' | 'a'..'f' | 'A'..'F' -> loop_hex (i + 1)
  292. | _ -> String.sub s 0 i
  293. in
  294. let rec loop sp i =
  295. if i = String.length s then (if sp = 0 then s else String.sub s sp (i - sp)) else
  296. match String.unsafe_get s i with
  297. | '0'..'9' -> loop sp (i + 1)
  298. | ' ' when sp = i -> loop (sp + 1) (i + 1)
  299. | '-' when i = 0 -> loop sp (i + 1)
  300. | ('x' | 'X') when i = 1 && String.get s 0 = '0' -> loop_hex (i + 1)
  301. | _ -> String.sub s sp (i - sp)
  302. in
  303. best_int (Int32.of_string (loop 0 0))
  304. let parse_float s =
  305. let rec loop sp i =
  306. if i = String.length s then (if sp = 0 then s else String.sub s sp (i - sp)) else
  307. match String.unsafe_get s i with
  308. | ' ' when sp = i -> loop (sp + 1) (i + 1)
  309. | '0'..'9' | '-' | '+' | 'e' | 'E' | '.' -> loop sp (i + 1)
  310. | _ -> String.sub s sp (i - sp)
  311. in
  312. float_of_string (loop 0 0)
  313. let find_sub str sub start =
  314. let sublen = String.length sub in
  315. if sublen = 0 then
  316. 0
  317. else
  318. let found = ref 0 in
  319. let len = String.length str in
  320. try
  321. for i = start to len - sublen do
  322. let j = ref 0 in
  323. while String.unsafe_get str (i + !j) = String.unsafe_get sub !j do
  324. incr j;
  325. if !j = sublen then begin found := i; raise Exit; end;
  326. done;
  327. done;
  328. raise Not_found
  329. with
  330. Exit -> !found
  331. let nargs = function
  332. | Fun0 _ -> 0
  333. | Fun1 _ -> 1
  334. | Fun2 _ -> 2
  335. | Fun3 _ -> 3
  336. | Fun4 _ -> 4
  337. | Fun5 _ -> 5
  338. | FunVar _ -> -1
  339. let rec get_field o fid =
  340. let rec loop min max =
  341. if min < max then begin
  342. let mid = (min + max) lsr 1 in
  343. let cid, v = Array.unsafe_get o.ofields mid in
  344. if cid < fid then
  345. loop (mid + 1) max
  346. else if cid > fid then
  347. loop min mid
  348. else
  349. v
  350. end else
  351. match o.oproto with
  352. | None -> VNull
  353. | Some p -> get_field p fid
  354. in
  355. loop 0 (Array.length o.ofields)
  356. let set_field o fid v =
  357. let rec loop min max =
  358. let mid = (min + max) lsr 1 in
  359. if min < max then begin
  360. let cid, _ = Array.unsafe_get o.ofields mid in
  361. if cid < fid then
  362. loop (mid + 1) max
  363. else if cid > fid then
  364. loop min mid
  365. else
  366. Array.unsafe_set o.ofields mid (cid,v)
  367. end else
  368. let fields = Array.make (Array.length o.ofields + 1) (fid,v) in
  369. Array.blit o.ofields 0 fields 0 mid;
  370. Array.blit o.ofields mid fields (mid + 1) (Array.length o.ofields - mid);
  371. o.ofields <- fields
  372. in
  373. loop 0 (Array.length o.ofields)
  374. let rec remove_field o fid =
  375. let rec loop min max =
  376. let mid = (min + max) lsr 1 in
  377. if min < max then begin
  378. let cid, v = Array.unsafe_get o.ofields mid in
  379. if cid < fid then
  380. loop (mid + 1) max
  381. else if cid > fid then
  382. loop min mid
  383. else begin
  384. let fields = Array.make (Array.length o.ofields - 1) (fid,VNull) in
  385. Array.blit o.ofields 0 fields 0 mid;
  386. Array.blit o.ofields (mid + 1) fields mid (Array.length o.ofields - mid - 1);
  387. o.ofields <- fields;
  388. true
  389. end
  390. end else
  391. false
  392. in
  393. loop 0 (Array.length o.ofields)
  394. let rec get_field_opt o fid =
  395. let rec loop min max =
  396. if min < max then begin
  397. let mid = (min + max) lsr 1 in
  398. let cid, v = Array.unsafe_get o.ofields mid in
  399. if cid < fid then
  400. loop (mid + 1) max
  401. else if cid > fid then
  402. loop min mid
  403. else
  404. Some v
  405. end else
  406. match o.oproto with
  407. | None -> None
  408. | Some p -> get_field_opt p fid
  409. in
  410. loop 0 (Array.length o.ofields)
  411. let catch_errors ctx ?(final=(fun() -> ())) f =
  412. let n = DynArray.length ctx.stack in
  413. try
  414. let v = f() in
  415. final();
  416. Some v
  417. with Runtime v ->
  418. pop ctx (DynArray.length ctx.stack - n);
  419. final();
  420. let rec loop o =
  421. if o == ctx.error_proto then true else match o.oproto with None -> false | Some p -> loop p
  422. in
  423. (match v with
  424. | VObject o when loop o ->
  425. (match get_field o (hash "message"), get_field o (hash "pos") with
  426. | VObject msg, VAbstract (APos pos) ->
  427. (match get_field msg h_s with
  428. | VString msg -> raise (Typecore.Error (Typecore.Custom msg,pos))
  429. | _ -> ());
  430. | _ -> ());
  431. | _ -> ());
  432. raise (Error (ctx.do_string v,List.map (fun s -> make_pos s.cpos) ctx.callstack))
  433. | Abort ->
  434. pop ctx (DynArray.length ctx.stack - n);
  435. final();
  436. None
  437. let make_library fl =
  438. let h = Hashtbl.create 0 in
  439. List.iter (fun (n,f) -> Hashtbl.add h n f) fl;
  440. h
  441. (* ---------------------------------------------------------------------- *)
  442. (* NEKO INTEROP *)
  443. type primitive = (string * Extc.value * int)
  444. type neko_context = {
  445. load : string -> int -> primitive;
  446. call : primitive -> value list -> value;
  447. }
  448. let neko =
  449. let is_win = Sys.os_type = "Win32" || Sys.os_type = "Cygwin" in
  450. let neko = Extc.dlopen (if is_win then "neko.dll" else "libneko.so") in
  451. let null = Extc.dlint 0 in
  452. let neko = if Obj.magic neko == null && not is_win then Extc.dlopen "libneko.dylib" else neko in
  453. if Obj.magic neko == null then
  454. None
  455. else
  456. let load v =
  457. let s = Extc.dlsym neko v in
  458. if (Obj.magic s) == null then failwith ("Could not load neko." ^ v);
  459. s
  460. in
  461. ignore(Extc.dlcall0 (load "neko_global_init"));
  462. let vm = Extc.dlcall1 (load "neko_vm_alloc") null in
  463. ignore(Extc.dlcall1 (load "neko_vm_select") vm);
  464. let loader = Extc.dlcall2 (load "neko_default_loader") null null in
  465. let loadprim =
  466. let l1 = load "neko_val_field" in
  467. let l2 = Extc.dlcall1 (load "neko_val_id") (Extc.dlstring "loadprim") in
  468. Extc.dlcall2 (l1) loader (l2) in
  469. let callN = load "neko_val_callN" in
  470. let callEx = load "neko_val_callEx" in
  471. let copy_string = load "neko_copy_string" in
  472. let alloc_root = load "neko_alloc_root" in
  473. let free_root = load "neko_free_root" in
  474. let alloc_root v =
  475. let r = Extc.dlcall1 alloc_root (Extc.dlint 1) in
  476. Extc.dlsetptr r v;
  477. r
  478. in
  479. let free_root r =
  480. ignore(Extc.dlcall1 free_root r)
  481. in
  482. ignore(alloc_root vm);
  483. ignore(alloc_root loader);
  484. ignore(alloc_root loadprim);
  485. let alloc_string s =
  486. Extc.dlcall2 copy_string (Extc.dlstring s) (Extc.dlint (String.length s))
  487. in
  488. let alloc_int (i:int) : Extc.value =
  489. Obj.magic i
  490. in
  491. let loadprim n args =
  492. let exc = ref null in
  493. let vargs = [|alloc_string n;alloc_int args|] in
  494. let p = Extc.dlcall5 callEx loader loadprim (Obj.magic vargs) (Extc.dlint 2) (Obj.magic exc) in
  495. if !exc != null then failwith ("Failed to load " ^ n ^ ":" ^ string_of_int args);
  496. ignore(alloc_root p);
  497. (n,p,args)
  498. in
  499. let call_raw_prim (_,p,nargs) (args:Extc.value array) =
  500. Extc.dlcall3 callN p (Obj.magic args) (Extc.dlint nargs)
  501. in
  502. (* a bit tricky since load "val_true" does not work as expected on Windows *)
  503. let unser = try loadprim "std@unserialize" 2 with _ -> ("",null,0) in
  504. (* did we fail to load std.ndll ? *)
  505. if (match unser with ("",_,_) -> true | _ -> false) then None else
  506. let val_true = call_raw_prim unser [|alloc_string "T";loader|] in
  507. let val_false = call_raw_prim unser [|alloc_string "F";loader|] in
  508. let val_null = call_raw_prim unser [|alloc_string "N";loader|] in
  509. let is_64 = call_raw_prim (loadprim "std@sys_is64" 0) [||] == val_true in
  510. let alloc_i32, is_v2 = (try load "neko_alloc_int32", true with _ -> Obj.magic 0, false) in
  511. let alloc_i32 = if is_v2 then
  512. (fun i -> Extc.dlcall1 alloc_i32 (Extc.dlint32 i))
  513. else
  514. (fun i -> alloc_int (Int32.to_int (if Int32.compare i Int32.zero < 0 then Int32.logand i 0x7FFFFFFFl else Int32.logor i 0x80000000l)))
  515. in
  516. let tag_bits = if is_v2 then 4 else 3 in
  517. let tag_mask = (1 lsl tag_bits) - 1 in
  518. let ptr_size = if is_64 then 8 else 4 in
  519. let val_field v i = Extc.dladdr v ((i + 1) * ptr_size) in
  520. let val_str v = Extc.dladdr v 4 in
  521. let val_fun_env v = Extc.dladdr v (8 + ptr_size) in
  522. (* alloc support *)
  523. let alloc_function = load "neko_alloc_function" in
  524. let alloc_array = load "neko_alloc_array" in
  525. let alloc_float = load "neko_alloc_float" in
  526. let alloc_object = load "neko_alloc_object" in
  527. let alloc_field = load "neko_alloc_field" in
  528. let alloc_abstract = load "neko_alloc_abstract" in
  529. let val_gc = load "neko_val_gc" in
  530. let val_field_name = load "neko_val_field_name" in
  531. let val_iter_fields = load "neko_val_iter_fields" in
  532. let gen_callback = Extc.dlcaml_callback 2 in
  533. (* roots *)
  534. let on_abstract_gc = Extc.dlcaml_callback 1 in
  535. let root_index = ref 0 in
  536. let roots = Hashtbl.create 0 in
  537. Callback.register "dlcallb1" (fun a ->
  538. let index : int = Obj.magic (Extc.dlptr (val_field a 1)) in
  539. Hashtbl.remove roots index;
  540. null
  541. );
  542. (* wrapping *)
  543. let copy_string v =
  544. let head = Extc.dltoint (Extc.dlptr v) in
  545. let size = head asr tag_bits in
  546. let s = String.create size in
  547. Extc.dlmemcpy (Extc.dlstring s) (val_str v) size;
  548. s
  549. in
  550. let buffers = ref [] in
  551. let rec value_neko ?(obj=VNull) = function
  552. | VNull -> val_null
  553. | VBool b -> if b then val_true else val_false
  554. | VInt i -> alloc_int i
  555. | VAbstract (ANekoAbstract a) -> a
  556. | VAbstract (ANekoBuffer (VString buf)) ->
  557. let v = value_neko (VString buf) in
  558. buffers := (buf,v) :: !buffers;
  559. v
  560. | VString s ->
  561. let v = alloc_string s in (* make a copy *)
  562. ignore(copy_string v);
  563. v
  564. | VObject o as obj ->
  565. let vo = Extc.dlcall1 alloc_object null in
  566. Array.iter (fun (id,v) ->
  567. ignore(Extc.dlcall3 alloc_field vo (Extc.dlint id) (value_neko ~obj v))
  568. ) o.ofields;
  569. vo
  570. | VClosure _ ->
  571. failwith "Closure not supported"
  572. | VFunction f ->
  573. let callb = Extc.dlcall3 alloc_function gen_callback (Extc.dlint (-1)) (Obj.magic "<callback>") in
  574. let index = !root_index in
  575. incr root_index;
  576. Hashtbl.add roots index (f,obj);
  577. let a = Extc.dlcall2 alloc_abstract null (Obj.magic index) in
  578. if Extc.dlptr (val_field a 1) != Obj.magic index then assert false;
  579. ignore(Extc.dlcall2 val_gc a on_abstract_gc);
  580. Extc.dlsetptr (val_fun_env callb) a;
  581. callb
  582. | VArray a ->
  583. let va = Extc.dlcall1 alloc_array (Extc.dlint (Array.length a)) in
  584. Array.iteri (fun i v ->
  585. Extc.dlsetptr (val_field va i) (value_neko v)
  586. ) a;
  587. va
  588. | VFloat f ->
  589. Extc.dlcall1 alloc_float (Obj.magic f)
  590. | VAbstract _ ->
  591. failwith "Abstract not supported"
  592. | VInt32 i ->
  593. alloc_i32 i
  594. in
  595. let obj_r = ref [] in
  596. let obj_fun = (fun v id -> obj_r := (v,id) :: !obj_r; val_null) in
  597. let rec neko_value (v:Extc.value) =
  598. if Obj.is_int (Obj.magic v) then
  599. VInt (Obj.magic v)
  600. else
  601. let head = Extc.dltoint (Extc.dlptr v) in
  602. match head land tag_mask with
  603. | 0 -> VNull
  604. | 2 -> VBool (v == val_true)
  605. | 3 -> VString (copy_string v)
  606. | 4 ->
  607. ignore(Extc.dlcall3 val_iter_fields v (Extc.dlcallback 2) (Obj.magic obj_fun));
  608. let r = !obj_r in
  609. obj_r := [];
  610. let ctx = get_ctx() in
  611. let fields = List.rev_map (fun (v,id) ->
  612. let iid = Extc.dltoint id in
  613. if not (Hashtbl.mem ctx.fields_cache iid) then begin
  614. let name = copy_string (Extc.dlcall1 val_field_name id) in
  615. ignore(hash_field ctx name);
  616. end;
  617. iid, neko_value v
  618. ) r in
  619. VObject { ofields = Array.of_list fields; oproto = None }
  620. | 5 ->
  621. VArray (Array.init (head asr tag_bits) (fun i -> neko_value (Extc.dlptr (val_field v i))))
  622. | 7 ->
  623. let r = alloc_root v in
  624. let a = ANekoAbstract v in
  625. Gc.finalise (fun _ -> free_root r) a;
  626. VAbstract a
  627. | t ->
  628. failwith ("Unsupported Neko value tag " ^ string_of_int t)
  629. in
  630. Callback.register "dlcallb2" (fun args nargs ->
  631. (* get back the VM env, which was set in value_neko *)
  632. let env = Extc.dlptr (Extc.dladdr vm (2 * ptr_size)) in
  633. (* extract the index stored in abstract data *)
  634. let index : int = Obj.magic (Extc.dlptr (val_field env 1)) in
  635. let f, obj = (try Hashtbl.find roots index with Not_found -> assert false) in
  636. let nargs = Extc.dltoint nargs in
  637. let rec loop i =
  638. if i = nargs then [] else neko_value (Extc.dlptr (Extc.dladdr args (i * ptr_size))) :: loop (i + 1)
  639. in
  640. let v = (get_ctx()).do_call obj (VFunction f) (loop 0) { psource = "<callback>"; pline = 0; } in
  641. value_neko v
  642. );
  643. let callprim (n,p,nargs) args =
  644. let arr = Array.of_list (List.map value_neko args) in
  645. let exc = ref null in
  646. if Array.length arr <> nargs then failwith n;
  647. let ret = Extc.dlcall5 callEx val_null p (Obj.magic arr) (Extc.dlint nargs) (Obj.magic exc) in
  648. if !exc != null then raise (Runtime (neko_value !exc));
  649. (match !buffers with
  650. | [] -> ()
  651. | l ->
  652. buffers := [];
  653. (* copy back data *)
  654. List.iter (fun (buf,v) ->
  655. Extc.dlmemcpy (Extc.dlstring buf) (val_str v) (String.length buf);
  656. ) l);
  657. neko_value ret
  658. in
  659. Some {
  660. load = loadprim;
  661. call = callprim;
  662. }
  663. (* ---------------------------------------------------------------------- *)
  664. (* BUILTINS *)
  665. let builtins =
  666. let p = { psource = "<builtin>"; pline = 0 } in
  667. let error() =
  668. raise Builtin_error
  669. in
  670. let vint = function
  671. | VInt n -> n
  672. | _ -> error()
  673. in
  674. let varray = function
  675. | VArray a -> a
  676. | _ -> error()
  677. in
  678. let vstring = function
  679. | VString s -> s
  680. | _ -> error()
  681. in
  682. let vobj = function
  683. | VObject o -> o
  684. | _ -> error()
  685. in
  686. let vfun = function
  687. | VFunction f -> f
  688. | VClosure (cl,f) -> FunVar (f cl)
  689. | _ -> error()
  690. in
  691. let vhash = function
  692. | VAbstract (AHash h) -> h
  693. | _ -> error()
  694. in
  695. let build_stack sl =
  696. let make p =
  697. let p = make_pos p in
  698. VArray [|VString p.Ast.pfile;VInt (Lexer.get_error_line p)|]
  699. in
  700. VArray (Array.of_list (List.map make sl))
  701. in
  702. let do_closure args args2 =
  703. match args with
  704. | f :: obj :: args ->
  705. (get_ctx()).do_call obj f (args @ args2) p
  706. | _ ->
  707. assert false
  708. in
  709. let funcs = [
  710. (* array *)
  711. "array", FunVar (fun vl -> VArray (Array.of_list vl));
  712. "amake", Fun1 (fun v -> VArray (Array.create (vint v) VNull));
  713. "acopy", Fun1 (fun a -> VArray (Array.copy (varray a)));
  714. "asize", Fun1 (fun a -> VInt (Array.length (varray a)));
  715. "asub", Fun3 (fun a p l -> VArray (Array.sub (varray a) (vint p) (vint l)));
  716. "ablit", Fun5 (fun dst dstp src p l ->
  717. Array.blit (varray src) (vint p) (varray dst) (vint dstp) (vint l);
  718. VNull
  719. );
  720. "aconcat", Fun1 (fun arr ->
  721. let arr = Array.map varray (varray arr) in
  722. VArray (Array.concat (Array.to_list arr))
  723. );
  724. (* string *)
  725. "string", Fun1 (fun v -> VString ((get_ctx()).do_string v));
  726. "smake", Fun1 (fun l -> VString (String.make (vint l) '\000'));
  727. "ssize", Fun1 (fun s -> VInt (String.length (vstring s)));
  728. "scopy", Fun1 (fun s -> VString (String.copy (vstring s)));
  729. "ssub", Fun3 (fun s p l -> VString (String.sub (vstring s) (vint p) (vint l)));
  730. "sget", Fun2 (fun s p ->
  731. try VInt (int_of_char (String.get (vstring s) (vint p))) with Invalid_argument _ -> VNull
  732. );
  733. "sset", Fun3 (fun s p c ->
  734. let c = char_of_int ((vint c) land 0xFF) in
  735. try
  736. String.set (vstring s) (vint p) c;
  737. VInt (int_of_char c)
  738. with Invalid_argument _ -> VNull);
  739. "sblit", Fun5 (fun dst dstp src p l ->
  740. String.blit (vstring src) (vint p) (vstring dst) (vint dstp) (vint l);
  741. VNull
  742. );
  743. "sfind", Fun3 (fun src pos pat ->
  744. try VInt (find_sub (vstring src) (vstring pat) (vint pos)) with Not_found -> VNull
  745. );
  746. (* object *)
  747. "new", Fun1 (fun o ->
  748. match o with
  749. | VNull -> VObject { ofields = [||]; oproto = None }
  750. | VObject o -> VObject { ofields = Array.copy o.ofields; oproto = o.oproto }
  751. | _ -> error()
  752. );
  753. "objget", Fun2 (fun o f ->
  754. match o with
  755. | VObject o -> get_field o (vint f)
  756. | _ -> VNull
  757. );
  758. "objset", Fun3 (fun o f v ->
  759. match o with
  760. | VObject o -> set_field o (vint f) v; v
  761. | _ -> VNull
  762. );
  763. "objcall", Fun3 (fun o f pl ->
  764. match o with
  765. | VObject oo ->
  766. (get_ctx()).do_call o (get_field oo (vint f)) (Array.to_list (varray pl)) p
  767. | _ -> VNull
  768. );
  769. "objfield", Fun2 (fun o f ->
  770. match o with
  771. | VObject o ->
  772. let p = o.oproto in
  773. o.oproto <- None;
  774. let v = get_field_opt o (vint f) in
  775. o.oproto <- p;
  776. VBool (v <> None)
  777. | _ -> VBool false
  778. );
  779. "objremove", Fun2 (fun o f ->
  780. VBool (remove_field (vobj o) (vint f))
  781. );
  782. "objfields", Fun1 (fun o ->
  783. VArray (Array.map (fun (fid,_) -> VInt fid) (vobj o).ofields)
  784. );
  785. "hash", Fun1 (fun v -> VInt (hash_field (get_ctx()) (vstring v)));
  786. "fasthash", Fun1 (fun v -> VInt (hash (vstring v)));
  787. "field", Fun1 (fun v ->
  788. try VString (Hashtbl.find (get_ctx()).fields_cache (vint v)) with Not_found -> VNull
  789. );
  790. "objsetproto", Fun2 (fun o p ->
  791. let o = vobj o in
  792. (match p with
  793. | VNull -> o.oproto <- None
  794. | VObject p -> o.oproto <- Some p
  795. | _ -> error());
  796. VNull;
  797. );
  798. "objgetproto", Fun1 (fun o ->
  799. match (vobj o).oproto with
  800. | None -> VNull
  801. | Some p -> VObject p
  802. );
  803. (* function *)
  804. "nargs", Fun1 (fun f ->
  805. VInt (nargs (vfun f))
  806. );
  807. "call", Fun3 (fun f o args ->
  808. (get_ctx()).do_call o f (Array.to_list (varray args)) p
  809. );
  810. "closure", FunVar (fun vl ->
  811. match vl with
  812. | VFunction f :: _ :: _ ->
  813. VClosure (vl, do_closure)
  814. | _ -> exc (VString "Can't create closure : value is not a function")
  815. );
  816. "apply", FunVar (fun vl ->
  817. match vl with
  818. | f :: args ->
  819. let f = vfun f in
  820. VFunction (FunVar (fun args2 -> (get_ctx()).do_call VNull (VFunction f) (args @ args2) p))
  821. | _ -> exc (VString "Invalid closure arguments number")
  822. );
  823. "varargs", Fun1 (fun f ->
  824. match f with
  825. | VFunction (FunVar _) | VFunction (Fun1 _) | VClosure _ ->
  826. VFunction (FunVar (fun vl -> (get_ctx()).do_call VNull f [VArray (Array.of_list vl)] p))
  827. | _ ->
  828. error()
  829. );
  830. (* numbers *)
  831. (* skip iadd, isub, idiv, imult *)
  832. "isnan", Fun1 (fun f ->
  833. match f with
  834. | VFloat f -> VBool (f <> f)
  835. | _ -> VBool false
  836. );
  837. "isinfinite", Fun1 (fun f ->
  838. match f with
  839. | VFloat f -> VBool (f = infinity || f = neg_infinity)
  840. | _ -> VBool false
  841. );
  842. "int", Fun1 (fun v ->
  843. match v with
  844. | VInt _ | VInt32 _ -> v
  845. | VFloat f -> best_int (to_int f)
  846. | VString s -> (try parse_int s with _ -> VNull)
  847. | _ -> VNull
  848. );
  849. "float", Fun1 (fun v ->
  850. match v with
  851. | VInt i -> VFloat (float_of_int i)
  852. | VInt32 i -> VFloat (Int32.to_float i)
  853. | VFloat _ -> v
  854. | VString s -> (try VFloat (parse_float s) with _ -> VNull)
  855. | _ -> VNull
  856. );
  857. (* abstract *)
  858. "getkind", Fun1 (fun v ->
  859. match v with
  860. | VAbstract a -> VAbstract (AKind a)
  861. | VInt32 _ -> VAbstract (AKind AInt32Kind)
  862. | _ -> error()
  863. );
  864. "iskind", Fun2 (fun v k ->
  865. match v, k with
  866. | VAbstract a, VAbstract (AKind k) -> VBool (Obj.tag (Obj.repr a) = Obj.tag (Obj.repr k))
  867. | VInt32 _, VAbstract (AKind AInt32Kind) -> VBool true
  868. | _, VAbstract (AKind _) -> VBool false
  869. | _ -> error()
  870. );
  871. (* hash *)
  872. "hkey", Fun1 (fun v -> VInt (Hashtbl.hash v));
  873. "hnew", Fun1 (fun v ->
  874. VAbstract (AHash (match v with
  875. | VNull -> Hashtbl.create 0
  876. | VInt n -> Hashtbl.create n
  877. | _ -> error()))
  878. );
  879. "hresize", Fun1 (fun v -> VNull);
  880. "hget", Fun3 (fun h k cmp ->
  881. if cmp <> VNull then assert false;
  882. (try Hashtbl.find (vhash h) k with Not_found -> VNull)
  883. );
  884. "hmem", Fun3 (fun h k cmp ->
  885. if cmp <> VNull then assert false;
  886. VBool (Hashtbl.mem (vhash h) k)
  887. );
  888. "hremove", Fun3 (fun h k cmp ->
  889. if cmp <> VNull then assert false;
  890. let h = vhash h in
  891. let old = Hashtbl.mem h k in
  892. if old then Hashtbl.remove h k;
  893. VBool old
  894. );
  895. "hset", Fun4 (fun h k v cmp ->
  896. if cmp <> VNull then assert false;
  897. let h = vhash h in
  898. let old = Hashtbl.mem h k in
  899. Hashtbl.replace h k v;
  900. VBool (not old);
  901. );
  902. "hadd", Fun4 (fun h k v cmp ->
  903. if cmp <> VNull then assert false;
  904. let h = vhash h in
  905. let old = Hashtbl.mem h k in
  906. Hashtbl.add h k v;
  907. VBool (not old);
  908. );
  909. "hiter", Fun2 (fun h f -> Hashtbl.iter (fun k v -> ignore ((get_ctx()).do_call VNull f [k;v] p)) (vhash h); VNull);
  910. "hcount", Fun1 (fun h -> VInt (Hashtbl.length (vhash h)));
  911. "hsize", Fun1 (fun h -> VInt (Hashtbl.length (vhash h)));
  912. (* misc *)
  913. "print", FunVar (fun vl -> List.iter (fun v ->
  914. let ctx = get_ctx() in
  915. let com = ctx.curapi.get_com() in
  916. com.print (ctx.do_string v)
  917. ) vl; VNull);
  918. "throw", Fun1 (fun v -> exc v);
  919. "rethrow", Fun1 (fun v ->
  920. let ctx = get_ctx() in
  921. ctx.callstack <- List.rev (List.map (fun p -> { cpos = p; cthis = ctx.vthis; cstack = DynArray.length ctx.stack; cenv = ctx.venv }) ctx.exc) @ ctx.callstack;
  922. exc v
  923. );
  924. "istrue", Fun1 (fun v ->
  925. match v with
  926. | VNull | VInt 0 | VBool false | VInt32 0l -> VBool false
  927. | _ -> VBool true
  928. );
  929. "not", Fun1 (fun v ->
  930. match v with
  931. | VNull | VInt 0 | VBool false | VInt32 0l -> VBool true
  932. | _ -> VBool false
  933. );
  934. "typeof", Fun1 (fun v ->
  935. VInt (match v with
  936. | VNull -> 0
  937. | VInt _ | VInt32 _ -> 1
  938. | VFloat _ -> 2
  939. | VBool _ -> 3
  940. | VString _ -> 4
  941. | VObject _ -> 5
  942. | VArray _ -> 6
  943. | VFunction _ | VClosure _ -> 7
  944. | VAbstract _ -> 8)
  945. );
  946. "compare", Fun2 (fun a b ->
  947. match (get_ctx()).do_compare a b with
  948. | CUndef -> VNull
  949. | CEq -> VInt 0
  950. | CSup -> VInt 1
  951. | CInf -> VInt (-1)
  952. );
  953. "pcompare", Fun2 (fun a b ->
  954. assert false
  955. );
  956. "excstack", Fun0 (fun() ->
  957. build_stack (get_ctx()).exc
  958. );
  959. "callstack", Fun0 (fun() ->
  960. build_stack (List.map (fun s -> s.cpos) (get_ctx()).callstack)
  961. );
  962. "version", Fun0 (fun() ->
  963. VInt 200
  964. );
  965. (* extra *)
  966. "use_neko_dll", Fun0 (fun() ->
  967. VBool (neko <> None)
  968. );
  969. ] in
  970. let vals = [
  971. "tnull", VInt 0;
  972. "tint", VInt 1;
  973. "tfloat", VInt 2;
  974. "tbool", VInt 3;
  975. "tstring", VInt 4;
  976. "tobject", VInt 5;
  977. "tarray", VInt 6;
  978. "tfunction", VInt 7;
  979. "tabstract", VInt 8;
  980. ] in
  981. let h = Hashtbl.create 0 in
  982. List.iter (fun (n,f) -> Hashtbl.add h n (VFunction f)) funcs;
  983. List.iter (fun (n,v) -> Hashtbl.add h n v) vals;
  984. h
  985. (* ---------------------------------------------------------------------- *)
  986. (* STD LIBRARY *)
  987. let free_abstract a =
  988. match a with
  989. | VAbstract vp -> Obj.set_tag (Obj.repr vp) 0 (* this will mute it as Deallocated *)
  990. | _ -> assert false
  991. let std_lib =
  992. let p = { psource = "<stdlib>"; pline = 0 } in
  993. let error() =
  994. raise Builtin_error
  995. in
  996. let make_list l =
  997. let rec loop acc = function
  998. | [] -> acc
  999. | x :: l -> loop (VArray [|x;acc|]) l
  1000. in
  1001. loop VNull (List.rev l)
  1002. in
  1003. let num = function
  1004. | VInt i -> float_of_int i
  1005. | VInt32 i -> Int32.to_float i
  1006. | VFloat f -> f
  1007. | _ -> error()
  1008. in
  1009. let make_date f =
  1010. VInt32 (Int32.of_float f)
  1011. in
  1012. let date = function
  1013. | VInt32 i -> Int32.to_float i
  1014. | VInt i -> float_of_int i
  1015. | _ -> error()
  1016. in
  1017. let make_i32 i =
  1018. VInt32 i
  1019. in
  1020. let int32 = function
  1021. | VInt i -> Int32.of_int i
  1022. | VInt32 i -> i
  1023. | _ -> error()
  1024. in
  1025. let vint = function
  1026. | VInt n -> n
  1027. | _ -> error()
  1028. in
  1029. let vstring = function
  1030. | VString s -> s
  1031. | _ -> error()
  1032. in
  1033. let int32_addr h =
  1034. let base = Int32.to_int (Int32.logand h 0xFFFFFFl) in
  1035. let str = Printf.sprintf "%ld.%d.%d.%d" (Int32.shift_right_logical h 24) (base lsr 16) ((base lsr 8) land 0xFF) (base land 0xFF) in
  1036. Unix.inet_addr_of_string str
  1037. in
  1038. let int32_op op = Fun2 (fun a b -> make_i32 (op (int32 a) (int32 b))) in
  1039. make_library ([
  1040. (* math *)
  1041. "math_atan2", Fun2 (fun a b -> VFloat (atan2 (num a) (num b)));
  1042. "math_pow", Fun2 (fun a b -> VFloat ((num a) ** (num b)));
  1043. "math_abs", Fun1 (fun v ->
  1044. match v with
  1045. | VInt i -> VInt (abs i)
  1046. | VInt32 i -> VInt32 (Int32.abs i)
  1047. | VFloat f -> VFloat (abs_float f)
  1048. | _ -> error()
  1049. );
  1050. "math_ceil", Fun1 (fun v -> match v with VInt _ | VInt32 _ -> v | _ -> best_int (to_int (ceil (num v))));
  1051. "math_floor", Fun1 (fun v -> match v with VInt _ | VInt32 _ -> v | _ -> best_int (to_int (floor (num v))));
  1052. "math_round", Fun1 (fun v -> match v with VInt _ | VInt32 _ -> v | _ -> best_int (to_int (floor (num v +. 0.5))));
  1053. "math_pi", Fun0 (fun() -> VFloat (4.0 *. atan 1.0));
  1054. "math_sqrt", Fun1 (fun v -> VFloat (sqrt (num v)));
  1055. "math_atan", Fun1 (fun v -> VFloat (atan (num v)));
  1056. "math_cos", Fun1 (fun v -> VFloat (cos (num v)));
  1057. "math_sin", Fun1 (fun v -> VFloat (sin (num v)));
  1058. "math_tan", Fun1 (fun v -> VFloat (tan (num v)));
  1059. "math_log", Fun1 (fun v -> VFloat (Pervasives.log (num v)));
  1060. "math_exp", Fun1 (fun v -> VFloat (exp (num v)));
  1061. "math_acos", Fun1 (fun v -> VFloat (acos (num v)));
  1062. "math_asin", Fun1 (fun v -> VFloat (asin (num v)));
  1063. "math_fceil", Fun1 (fun v -> VFloat (ceil (num v)));
  1064. "math_ffloor", Fun1 (fun v -> VFloat (floor (num v)));
  1065. "math_fround", Fun1 (fun v -> VFloat (floor (num v +. 0.5)));
  1066. "math_int", Fun1 (fun v ->
  1067. match v with
  1068. | VInt _ | VInt32 _ -> v
  1069. | VFloat f -> best_int (to_int (if f < 0. then ceil f else floor f))
  1070. | _ -> error()
  1071. );
  1072. (* buffer *)
  1073. "buffer_new", Fun0 (fun() ->
  1074. VAbstract (ABuffer (Buffer.create 0))
  1075. );
  1076. "buffer_add", Fun2 (fun b v ->
  1077. match b with
  1078. | VAbstract (ABuffer b) -> Buffer.add_string b ((get_ctx()).do_string v); VNull
  1079. | _ -> error()
  1080. );
  1081. "buffer_add_char", Fun2 (fun b v ->
  1082. match b, v with
  1083. | VAbstract (ABuffer b), VInt n when n >= 0 && n < 256 -> Buffer.add_char b (char_of_int n); VNull
  1084. | _ -> error()
  1085. );
  1086. "buffer_add_sub", Fun4 (fun b s p l ->
  1087. match b, s, p, l with
  1088. | VAbstract (ABuffer b), VString s, VInt p, VInt l -> (try Buffer.add_substring b s p l; VNull with _ -> error())
  1089. | _ -> error()
  1090. );
  1091. "buffer_string", Fun1 (fun b ->
  1092. match b with
  1093. | VAbstract (ABuffer b) -> VString (Buffer.contents b)
  1094. | _ -> error()
  1095. );
  1096. "buffer_reset", Fun1 (fun b ->
  1097. match b with
  1098. | VAbstract (ABuffer b) -> Buffer.reset b; VNull;
  1099. | _ -> error()
  1100. );
  1101. "buffer_get_length", Fun1 (fun b ->
  1102. match b with
  1103. | VAbstract (ABuffer b) -> VInt (Buffer.length b)
  1104. | _ -> error()
  1105. );
  1106. (* date *)
  1107. "date_now", Fun0 (fun () ->
  1108. make_date (Unix.time())
  1109. );
  1110. "date_new", Fun1 (fun v ->
  1111. make_date (match v with
  1112. | VNull -> Unix.time()
  1113. | VString s ->
  1114. (match String.length s with
  1115. | 19 ->
  1116. let r = Str.regexp "^\\([0-9][0-9][0-9][0-9]\\)-\\([0-9][0-9]\\)-\\([0-9][0-9]\\) \\([0-9][0-9]\\):\\([0-9][0-9]\\):\\([0-9][0-9]\\)$" in
  1117. if not (Str.string_match r s 0) then exc (VString ("Invalid date format : " ^ s));
  1118. let t = Unix.localtime (Unix.time()) in
  1119. let t = { t with
  1120. tm_year = int_of_string (Str.matched_group 1 s) - 1900;
  1121. tm_mon = int_of_string (Str.matched_group 2 s) - 1;
  1122. tm_mday = int_of_string (Str.matched_group 3 s);
  1123. tm_hour = int_of_string (Str.matched_group 4 s);
  1124. tm_min = int_of_string (Str.matched_group 5 s);
  1125. tm_sec = int_of_string (Str.matched_group 6 s);
  1126. } in
  1127. fst (Unix.mktime t)
  1128. | 10 ->
  1129. assert false
  1130. | 8 ->
  1131. assert false
  1132. | _ ->
  1133. exc (VString ("Invalid date format : " ^ s)));
  1134. | _ -> error())
  1135. );
  1136. "date_set_hour", Fun4 (fun d h m s ->
  1137. let d = date d in
  1138. let t = Unix.localtime d in
  1139. make_date (fst (Unix.mktime { t with tm_hour = vint h; tm_min = vint m; tm_sec = vint s }))
  1140. );
  1141. "date_set_day", Fun4 (fun d y m da ->
  1142. let d = date d in
  1143. let t = Unix.localtime d in
  1144. make_date (fst (Unix.mktime { t with tm_year = vint y - 1900; tm_mon = vint m - 1; tm_mday = vint da }))
  1145. );
  1146. "date_format", Fun2 (fun d fmt ->
  1147. match fmt with
  1148. | VNull ->
  1149. let t = Unix.localtime (date d) in
  1150. VString (Printf.sprintf "%.4d-%.2d-%.2d %.2d:%.2d:%.2d" (t.tm_year + 1900) (t.tm_mon + 1) t.tm_mday t.tm_hour t.tm_min t.tm_sec)
  1151. | VString "%w" ->
  1152. (* week day *)
  1153. let t = Unix.localtime (date d) in
  1154. VString (string_of_int t.tm_wday)
  1155. | VString _ ->
  1156. exc (VString "Custom date format is not supported") (* use native Haxe implementation *)
  1157. | _ ->
  1158. error()
  1159. );
  1160. "date_get_hour", Fun1 (fun d ->
  1161. let t = Unix.localtime (date d) in
  1162. let o = obj (hash_field (get_ctx())) [
  1163. "h", VInt t.tm_hour;
  1164. "m", VInt t.tm_min;
  1165. "s", VInt t.tm_sec;
  1166. ] in
  1167. VObject o
  1168. );
  1169. "date_get_day", Fun1 (fun d ->
  1170. let t = Unix.localtime (date d) in
  1171. let o = obj (hash_field (get_ctx())) [
  1172. "d", VInt t.tm_mday;
  1173. "m", VInt (t.tm_mon + 1);
  1174. "y", VInt (t.tm_year + 1900);
  1175. ] in
  1176. VObject o
  1177. );
  1178. (* string *)
  1179. "string_split", Fun2 (fun s d ->
  1180. make_list (match s, d with
  1181. | VString "", VString _ -> [VString ""]
  1182. | VString s, VString "" -> Array.to_list (Array.init (String.length s) (fun i -> VString (String.make 1 (String.get s i))))
  1183. | VString s, VString d -> List.map (fun s -> VString s) (ExtString.String.nsplit s d)
  1184. | _ -> error())
  1185. );
  1186. "url_encode", Fun1 (fun s ->
  1187. let s = vstring s in
  1188. let b = Buffer.create 0 in
  1189. let hex = "0123456789ABCDEF" in
  1190. for i = 0 to String.length s - 1 do
  1191. let c = String.unsafe_get s i in
  1192. match c with
  1193. | 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' | '-' | '.' ->
  1194. Buffer.add_char b c
  1195. | _ ->
  1196. Buffer.add_char b '%';
  1197. Buffer.add_char b (String.unsafe_get hex (int_of_char c lsr 4));
  1198. Buffer.add_char b (String.unsafe_get hex (int_of_char c land 0xF));
  1199. done;
  1200. VString (Buffer.contents b)
  1201. );
  1202. "url_decode", Fun1 (fun s ->
  1203. let s = vstring s in
  1204. let b = Buffer.create 0 in
  1205. let len = String.length s in
  1206. let decode c =
  1207. match c with
  1208. | '0'..'9' -> Some (int_of_char c - int_of_char '0')
  1209. | 'a'..'f' -> Some (int_of_char c - int_of_char 'a' + 10)
  1210. | 'A'..'F' -> Some (int_of_char c - int_of_char 'A' + 10)
  1211. | _ -> None
  1212. in
  1213. let rec loop i =
  1214. if i = len then () else
  1215. let c = String.unsafe_get s i in
  1216. match c with
  1217. | '%' ->
  1218. let p1 = (try decode (String.get s (i + 1)) with _ -> None) in
  1219. let p2 = (try decode (String.get s (i + 2)) with _ -> None) in
  1220. (match p1, p2 with
  1221. | Some c1, Some c2 ->
  1222. Buffer.add_char b (char_of_int ((c1 lsl 4) lor c2));
  1223. loop (i + 3)
  1224. | _ ->
  1225. loop (i + 1));
  1226. | '+' ->
  1227. Buffer.add_char b ' ';
  1228. loop (i + 1)
  1229. | c ->
  1230. Buffer.add_char b c;
  1231. loop (i + 1)
  1232. in
  1233. loop 0;
  1234. VString (Buffer.contents b)
  1235. );
  1236. "base_encode", Fun2 (fun s b ->
  1237. match s, b with
  1238. | VString s, VString "0123456789abcdef" when String.length s = 16 ->
  1239. VString (Digest.to_hex s)
  1240. | VString s, VString b ->
  1241. if String.length b <> 64 then assert false;
  1242. let tbl = Array.init 64 (String.unsafe_get b) in
  1243. VString (Base64.str_encode ~tbl s)
  1244. | _ -> error()
  1245. );
  1246. "base_decode", Fun2 (fun s b ->
  1247. let s = vstring s in
  1248. let b = vstring b in
  1249. if String.length b <> 64 then assert false;
  1250. let tbl = Array.init 64 (String.unsafe_get b) in
  1251. VString (Base64.str_decode ~tbl:(Base64.make_decoding_table tbl) s)
  1252. );
  1253. "make_md5", Fun1 (fun s ->
  1254. VString (Digest.string (vstring s))
  1255. );
  1256. (* sprintf *)
  1257. (* int32 *)
  1258. "int32_new", Fun1 (fun v ->
  1259. match v with
  1260. | VInt32 _ -> v
  1261. | VInt i -> make_i32 (Int32.of_int i)
  1262. | VFloat f -> make_i32 (Int32.of_float f)
  1263. | _ -> error()
  1264. );
  1265. "int32_to_int", Fun1 (fun v ->
  1266. let v = int32 v in
  1267. let i = Int32.to_int v in
  1268. if Int32.compare (Int32.of_int i) v <> 0 then error();
  1269. VInt i
  1270. );
  1271. "int32_to_float", Fun1 (fun v ->
  1272. VFloat (Int32.to_float (int32 v))
  1273. );
  1274. "int32_compare", Fun2 (fun a b ->
  1275. VInt (Int32.compare (int32 a) (int32 b))
  1276. );
  1277. "int32_add", int32_op Int32.add;
  1278. "int32_sub", int32_op Int32.sub;
  1279. "int32_mul", int32_op Int32.mul;
  1280. "int32_div", int32_op Int32.div;
  1281. "int32_shl", int32_op (fun a b -> Int32.shift_left a (Int32.to_int b));
  1282. "int32_shr", int32_op (fun a b -> Int32.shift_right a (Int32.to_int b));
  1283. "int32_ushr", int32_op (fun a b -> Int32.shift_right_logical a (Int32.to_int b));
  1284. "int32_mod", int32_op Int32.rem;
  1285. "int32_or", int32_op Int32.logor;
  1286. "int32_and", int32_op Int32.logand;
  1287. "int32_xor", int32_op Int32.logxor;
  1288. "int32_neg", Fun1 (fun v -> make_i32 (Int32.neg (int32 v)));
  1289. "int32_complement", Fun1 (fun v -> make_i32 (Int32.lognot (int32 v)));
  1290. (* misc *)
  1291. "same_closure", Fun2 (fun a b ->
  1292. VBool (match a, b with
  1293. | VClosure (la,fa), VClosure (lb,fb) ->
  1294. fa == fb && List.length la = List.length lb && List.for_all2 (fun a b -> (get_ctx()).do_compare a b = CEq) la lb
  1295. | VFunction a, VFunction b -> a == b
  1296. | _ -> false)
  1297. );
  1298. "double_bytes", Fun2 (fun f big ->
  1299. let f = (match f with VFloat f -> f | VInt i -> float_of_int i | _ -> error()) in
  1300. match big with
  1301. | VBool big ->
  1302. let ch = IO.output_string() in
  1303. if big then IO.BigEndian.write_double ch f else IO.write_double ch f;
  1304. VString (IO.close_out ch)
  1305. | _ ->
  1306. error()
  1307. );
  1308. "float_bytes", Fun2 (fun f big ->
  1309. let f = (match f with VFloat f -> f | VInt i -> float_of_int i | _ -> error()) in
  1310. match big with
  1311. | VBool big ->
  1312. let ch = IO.output_string() in
  1313. let i = Int32.bits_of_float f in
  1314. if big then IO.BigEndian.write_real_i32 ch i else IO.write_real_i32 ch i;
  1315. VString (IO.close_out ch)
  1316. | _ ->
  1317. error()
  1318. );
  1319. "double_of_bytes", Fun2 (fun s big ->
  1320. match s, big with
  1321. | VString s, VBool big when String.length s = 8 ->
  1322. let ch = IO.input_string s in
  1323. VFloat (if big then IO.BigEndian.read_double ch else IO.read_double ch)
  1324. | _ ->
  1325. error()
  1326. );
  1327. "float_of_bytes", Fun2 (fun s big ->
  1328. match s, big with
  1329. | VString s, VBool big when String.length s = 4 ->
  1330. let ch = IO.input_string s in
  1331. VFloat (Int32.float_of_bits (if big then IO.BigEndian.read_real_i32 ch else IO.read_real_i32 ch))
  1332. | _ ->
  1333. error()
  1334. );
  1335. (* random *)
  1336. "random_new", Fun0 (fun() -> VAbstract (ARandom (ref (Random.State.make_self_init()))));
  1337. "random_set_seed", Fun2 (fun r s ->
  1338. match r, s with
  1339. | VAbstract (ARandom r), VInt seed -> r := Random.State.make [|seed|]; VNull
  1340. | VAbstract (ARandom r), VInt32 seed -> r := Random.State.make [|Int32.to_int seed|]; VNull
  1341. | _ -> error()
  1342. );
  1343. "random_int", Fun2 (fun r s ->
  1344. match r, s with
  1345. | VAbstract (ARandom r), VInt max -> VInt (Random.State.int (!r) (if max <= 0 then 1 else max))
  1346. | _ -> error()
  1347. );
  1348. "random_float", Fun1 (fun r ->
  1349. match r with
  1350. | VAbstract (ARandom r) -> VFloat (Random.State.float (!r) 1.0)
  1351. | _ -> error()
  1352. );
  1353. (* file *)
  1354. "file_open", Fun2 (fun f r ->
  1355. match f, r with
  1356. | VString f, VString r ->
  1357. let perms = 0o666 in
  1358. VAbstract (match r with
  1359. | "r" -> AFRead (open_in_gen [Open_rdonly] 0 f,ref false)
  1360. | "rb" -> AFRead (open_in_gen [Open_rdonly;Open_binary] 0 f,ref false)
  1361. | "w" -> AFWrite (open_out_gen [Open_wronly;Open_creat;Open_trunc] perms f)
  1362. | "wb" -> AFWrite (open_out_gen [Open_wronly;Open_creat;Open_trunc;Open_binary] perms f)
  1363. | "a" -> AFWrite (open_out_gen [Open_append] perms f)
  1364. | "ab" -> AFWrite (open_out_gen [Open_append;Open_binary] perms f)
  1365. | _ -> error())
  1366. | _ -> error()
  1367. );
  1368. "file_close", Fun1 (fun vf ->
  1369. (match vf with
  1370. | VAbstract (AFRead (f,_)) -> close_in f; free_abstract vf;
  1371. | VAbstract (AFWrite f) -> close_out f; free_abstract vf;
  1372. | _ -> error());
  1373. VNull
  1374. );
  1375. (* file_name *)
  1376. "file_write", Fun4 (fun f s p l ->
  1377. match f, s, p, l with
  1378. | VAbstract (AFWrite f), VString s, VInt p, VInt l -> output f s p l; VInt l
  1379. | _ -> error()
  1380. );
  1381. "file_read", Fun4 (fun f s p l ->
  1382. match f, s, p, l with
  1383. | VAbstract (AFRead (f,r)), VString s, VInt p, VInt l ->
  1384. let n = input f s p l in
  1385. if n = 0 then begin
  1386. r := true;
  1387. exc (VArray [|VString "file_read"|]);
  1388. end;
  1389. VInt n
  1390. | _ -> error()
  1391. );
  1392. "file_write_char", Fun2 (fun f c ->
  1393. match f, c with
  1394. | VAbstract (AFWrite f), VInt c -> output_char f (char_of_int c); VNull
  1395. | _ -> error()
  1396. );
  1397. "file_read_char", Fun1 (fun f ->
  1398. match f with
  1399. | VAbstract (AFRead (f,r)) -> VInt (int_of_char (try input_char f with _ -> r := true; exc (VArray [|VString "file_read_char"|])))
  1400. | _ -> error()
  1401. );
  1402. "file_seek", Fun3 (fun f pos mode ->
  1403. match f, pos, mode with
  1404. | VAbstract (AFRead (f,r)), VInt pos, VInt mode ->
  1405. r := false;
  1406. seek_in f (match mode with 0 -> pos | 1 -> pos_in f + pos | 2 -> in_channel_length f + pos | _ -> error());
  1407. VNull;
  1408. | VAbstract (AFWrite f), VInt pos, VInt mode ->
  1409. seek_out f (match mode with 0 -> pos | 1 -> pos_out f + pos | 2 -> out_channel_length f + pos | _ -> error());
  1410. VNull;
  1411. | _ -> error()
  1412. );
  1413. "file_tell", Fun1 (fun f ->
  1414. match f with
  1415. | VAbstract (AFRead (f,_)) -> VInt (pos_in f)
  1416. | VAbstract (AFWrite f) -> VInt (pos_out f)
  1417. | _ -> error()
  1418. );
  1419. "file_eof", Fun1 (fun f ->
  1420. match f with
  1421. | VAbstract (AFRead (f,r)) ->
  1422. VBool !r
  1423. | _ -> error()
  1424. );
  1425. "file_flush", Fun1 (fun f ->
  1426. (match f with
  1427. | VAbstract (AFWrite f) -> flush f
  1428. | _ -> error());
  1429. VNull
  1430. );
  1431. "file_contents", Fun1 (fun f ->
  1432. match f with
  1433. | VString f -> VString (Std.input_file ~bin:true f)
  1434. | _ -> error()
  1435. );
  1436. "file_stdin", Fun0 (fun() -> VAbstract (AFRead (Pervasives.stdin, ref false)));
  1437. "file_stdout", Fun0 (fun() -> VAbstract (AFWrite Pervasives.stdout));
  1438. "file_stderr", Fun0 (fun() -> VAbstract (AFWrite Pervasives.stderr));
  1439. (* serialize *)
  1440. (* TODO *)
  1441. (* socket *)
  1442. "socket_init", Fun0 (fun() -> VNull);
  1443. "socket_new", Fun1 (fun v ->
  1444. match v with
  1445. | VBool b -> VAbstract (ASocket (Unix.socket PF_INET (if b then SOCK_DGRAM else SOCK_STREAM) 0));
  1446. | _ -> error()
  1447. );
  1448. "socket_close", Fun1 (fun vs ->
  1449. match vs with
  1450. | VAbstract (ASocket s) -> Unix.close s; free_abstract vs; VNull
  1451. | _ -> error()
  1452. );
  1453. "socket_send_char", Fun2 (fun s c ->
  1454. match s, c with
  1455. | VAbstract (ASocket s), VInt c when c >= 0 && c <= 255 ->
  1456. ignore(Unix.send s (String.make 1 (char_of_int c)) 0 1 []);
  1457. VNull
  1458. | _ -> error()
  1459. );
  1460. "socket_send", Fun4 (fun s buf pos len ->
  1461. match s, buf, pos, len with
  1462. | VAbstract (ASocket s), VString buf, VInt pos, VInt len -> VInt (Unix.send s buf pos len [])
  1463. | _ -> error()
  1464. );
  1465. "socket_recv", Fun4 (fun s buf pos len ->
  1466. match s, buf, pos, len with
  1467. | VAbstract (ASocket s), VString buf, VInt pos, VInt len -> VInt (Unix.recv s buf pos len [])
  1468. | _ -> error()
  1469. );
  1470. "socket_recv_char", Fun1 (fun s ->
  1471. match s with
  1472. | VAbstract (ASocket s) ->
  1473. let buf = String.make 1 '\000' in
  1474. ignore(Unix.recv s buf 0 1 []);
  1475. VInt (int_of_char (String.unsafe_get buf 0))
  1476. | _ -> error()
  1477. );
  1478. "socket_write", Fun2 (fun s str ->
  1479. match s, str with
  1480. | VAbstract (ASocket s), VString str ->
  1481. let pos = ref 0 in
  1482. let len = ref (String.length str) in
  1483. while !len > 0 do
  1484. let k = Unix.send s str (!pos) (!len) [] in
  1485. pos := !pos + k;
  1486. len := !len - k;
  1487. done;
  1488. VNull
  1489. | _ -> error()
  1490. );
  1491. "socket_read", Fun1 (fun s ->
  1492. match s with
  1493. | VAbstract (ASocket s) ->
  1494. let tmp = String.make 1024 '\000' in
  1495. let buf = Buffer.create 0 in
  1496. let rec loop() =
  1497. let k = (try Unix.recv s tmp 0 1024 [] with Unix_error _ -> 0) in
  1498. if k > 0 then begin
  1499. Buffer.add_substring buf tmp 0 k;
  1500. loop();
  1501. end
  1502. in
  1503. loop();
  1504. VString (Buffer.contents buf)
  1505. | _ -> error()
  1506. );
  1507. "host_resolve", Fun1 (fun s ->
  1508. let h = (try Unix.gethostbyname (vstring s) with Not_found -> error()) in
  1509. let addr = Unix.string_of_inet_addr h.h_addr_list.(0) in
  1510. let a, b, c, d = Scanf.sscanf addr "%d.%d.%d.%d" (fun a b c d -> a,b,c,d) in
  1511. VInt32 (Int32.logor (Int32.shift_left (Int32.of_int a) 24) (Int32.of_int (d lor (c lsl 8) lor (b lsl 16))))
  1512. );
  1513. "host_to_string", Fun1 (fun h ->
  1514. match h with
  1515. | VInt32 h -> VString (Unix.string_of_inet_addr (int32_addr h));
  1516. | _ -> error()
  1517. );
  1518. "host_reverse", Fun1 (fun h ->
  1519. match h with
  1520. | VInt32 h -> VString (gethostbyaddr (int32_addr h)).h_name
  1521. | _ -> error()
  1522. );
  1523. "host_local", Fun0 (fun() ->
  1524. VString (Unix.gethostname())
  1525. );
  1526. "socket_connect", Fun3 (fun s h p ->
  1527. match s, h, p with
  1528. | VAbstract (ASocket s), VInt32 h, VInt p ->
  1529. Unix.connect s (ADDR_INET (int32_addr h,p));
  1530. VNull
  1531. | _ -> error()
  1532. );
  1533. "socket_listen", Fun2 (fun s l ->
  1534. match s, l with
  1535. | VAbstract (ASocket s), VInt l ->
  1536. Unix.listen s l;
  1537. VNull
  1538. | _ -> error()
  1539. );
  1540. "socket_set_timeout", Fun2 (fun s t ->
  1541. match s with
  1542. | VAbstract (ASocket s) ->
  1543. let t = (match t with VNull -> 0. | VInt t -> float_of_int t | VFloat f -> f | _ -> error()) in
  1544. Unix.setsockopt_float s SO_RCVTIMEO t;
  1545. Unix.setsockopt_float s SO_SNDTIMEO t;
  1546. VNull
  1547. | _ -> error()
  1548. );
  1549. "socket_shutdown", Fun3 (fun s r w ->
  1550. match s, r, w with
  1551. | VAbstract (ASocket s), VBool r, VBool w ->
  1552. Unix.shutdown s (match r, w with true, true -> SHUTDOWN_ALL | true, false -> SHUTDOWN_RECEIVE | false, true -> SHUTDOWN_SEND | _ -> error());
  1553. VNull
  1554. | _ -> error()
  1555. );
  1556. (* TODO : select, bind, accept, peer, host *)
  1557. (* poll_alloc, poll : not planned *)
  1558. (* system *)
  1559. "get_env", Fun1 (fun v ->
  1560. try VString (Unix.getenv (vstring v)) with _ -> VNull
  1561. );
  1562. "put_env", Fun2 (fun e v ->
  1563. Unix.putenv (vstring e) (vstring v);
  1564. VNull
  1565. );
  1566. "sys_sleep", Fun1 (fun f ->
  1567. match f with
  1568. | VFloat f -> ignore(Unix.select [] [] [] f); VNull
  1569. | _ -> error()
  1570. );
  1571. "set_time_locale", Fun1 (fun l ->
  1572. match l with
  1573. | VString s -> VBool false (* always fail *)
  1574. | _ -> error()
  1575. );
  1576. "get_cwd", Fun0 (fun() ->
  1577. let dir = Unix.getcwd() in
  1578. let l = String.length dir in
  1579. VString (if l = 0 then "./" else match dir.[l - 1] with '/' | '\\' -> dir | _ -> dir ^ "/")
  1580. );
  1581. "set_cwd", Fun1 (fun s ->
  1582. Unix.chdir (vstring s);
  1583. VNull;
  1584. );
  1585. "sys_string", (
  1586. let cached_sys_name = ref None in
  1587. Fun0 (fun() ->
  1588. VString (match Sys.os_type with
  1589. | "Unix" ->
  1590. (match !cached_sys_name with
  1591. | Some n -> n
  1592. | None ->
  1593. let ic = Unix.open_process_in "uname" in
  1594. let uname = (match input_line ic with
  1595. | "Darwin" -> "Mac"
  1596. | n -> n
  1597. ) in
  1598. close_in ic;
  1599. cached_sys_name := Some uname;
  1600. uname)
  1601. | "Win32" | "Cygwin" -> "Windows"
  1602. | s -> s)
  1603. )
  1604. );
  1605. "sys_is64", Fun0 (fun() ->
  1606. VBool (Sys.word_size = 64)
  1607. );
  1608. "sys_command", Fun1 (fun cmd ->
  1609. VInt (((get_ctx()).curapi.get_com()).run_command (vstring cmd))
  1610. );
  1611. "sys_exit", Fun1 (fun code ->
  1612. if (get_ctx()).curapi.use_cache() then raise (Typecore.Fatal_error ("",Ast.null_pos));
  1613. raise (Sys_exit(vint code));
  1614. );
  1615. "sys_exists", Fun1 (fun file ->
  1616. VBool (Sys.file_exists (vstring file))
  1617. );
  1618. "file_delete", Fun1 (fun file ->
  1619. Sys.remove (vstring file);
  1620. VNull;
  1621. );
  1622. "sys_rename", Fun2 (fun file target ->
  1623. Sys.rename (vstring file) (vstring target);
  1624. VNull;
  1625. );
  1626. "sys_stat", Fun1 (fun file ->
  1627. let s = Unix.stat (vstring file) in
  1628. VObject (obj (hash_field (get_ctx())) [
  1629. "gid", VInt s.st_gid;
  1630. "uid", VInt s.st_uid;
  1631. "atime", VInt32 (Int32.of_float s.st_atime);
  1632. "mtime", VInt32 (Int32.of_float s.st_mtime);
  1633. "ctime", VInt32 (Int32.of_float s.st_ctime);
  1634. "dev", VInt s.st_dev;
  1635. "ino", VInt s.st_ino;
  1636. "nlink", VInt s.st_nlink;
  1637. "rdev", VInt s.st_rdev;
  1638. "size", VInt s.st_size;
  1639. "mode", VInt s.st_perm;
  1640. ])
  1641. );
  1642. "sys_file_type", Fun1 (fun file ->
  1643. VString (match (Unix.stat (vstring file)).st_kind with
  1644. | S_REG -> "file"
  1645. | S_DIR -> "dir"
  1646. | S_CHR -> "char"
  1647. | S_BLK -> "block"
  1648. | S_LNK -> "symlink"
  1649. | S_FIFO -> "fifo"
  1650. | S_SOCK -> "sock")
  1651. );
  1652. "sys_create_dir", Fun2 (fun dir mode ->
  1653. Unix.mkdir (vstring dir) (vint mode);
  1654. VNull
  1655. );
  1656. "sys_remove_dir", Fun1 (fun dir ->
  1657. Unix.rmdir (vstring dir);
  1658. VNull;
  1659. );
  1660. "sys_time", Fun0 (fun() ->
  1661. VFloat (Unix.gettimeofday())
  1662. );
  1663. "sys_cpu_time", Fun0 (fun() ->
  1664. VFloat (Sys.time())
  1665. );
  1666. "sys_read_dir", Fun1 (fun dir ->
  1667. let d = Sys.readdir (vstring dir) in
  1668. let rec loop acc i =
  1669. if i < 0 then
  1670. acc
  1671. else
  1672. loop (VArray [|VString d.(i);acc|]) (i - 1)
  1673. in
  1674. loop VNull (Array.length d - 1)
  1675. );
  1676. "file_full_path", Fun1 (fun file ->
  1677. VString (try Extc.get_full_path (vstring file) with _ -> error())
  1678. );
  1679. "sys_exe_path", Fun0 (fun() ->
  1680. VString (Sys.argv.(0))
  1681. );
  1682. "sys_env", Fun0 (fun() ->
  1683. let env = Unix.environment() in
  1684. let rec loop acc i =
  1685. if i < 0 then
  1686. acc
  1687. else
  1688. let e, v = ExtString.String.split env.(i) "=" in
  1689. loop (VArray [|VString e;VString v;acc|]) (i - 1)
  1690. in
  1691. loop VNull (Array.length env - 1)
  1692. );
  1693. "sys_getch", Fun1 (fun echo ->
  1694. match echo with
  1695. | VBool b -> VInt (Extc.getch b)
  1696. | _ -> error()
  1697. );
  1698. "sys_get_pid", Fun0 (fun() ->
  1699. VInt (Unix.getpid())
  1700. );
  1701. (* utf8 *)
  1702. "utf8_buf_alloc", Fun1 (fun v ->
  1703. VAbstract (AUtf8 (UTF8.Buf.create (vint v)))
  1704. );
  1705. "utf8_buf_add", Fun2 (fun b c ->
  1706. match b with
  1707. | VAbstract (AUtf8 buf) -> UTF8.Buf.add_char buf (UChar.chr_of_uint (vint c)); VNull
  1708. | _ -> error()
  1709. );
  1710. "utf8_buf_content", Fun1 (fun b ->
  1711. match b with
  1712. | VAbstract (AUtf8 buf) -> VString (UTF8.Buf.contents buf);
  1713. | _ -> error()
  1714. );
  1715. "utf8_buf_length", Fun1 (fun b ->
  1716. match b with
  1717. | VAbstract (AUtf8 buf) -> VInt (UTF8.length (UTF8.Buf.contents buf));
  1718. | _ -> error()
  1719. );
  1720. "utf8_buf_size", Fun1 (fun b ->
  1721. match b with
  1722. | VAbstract (AUtf8 buf) -> VInt (String.length (UTF8.Buf.contents buf));
  1723. | _ -> error()
  1724. );
  1725. "utf8_validate", Fun1 (fun s ->
  1726. VBool (try UTF8.validate (vstring s); true with UTF8.Malformed_code -> false)
  1727. );
  1728. "utf8_length", Fun1 (fun s ->
  1729. VInt (UTF8.length (vstring s))
  1730. );
  1731. "utf8_sub", Fun3 (fun s p l ->
  1732. let buf = UTF8.Buf.create 0 in
  1733. let pos = ref (-1) in
  1734. let p = vint p and l = vint l in
  1735. UTF8.iter (fun c ->
  1736. incr pos;
  1737. if !pos >= p && !pos < p + l then UTF8.Buf.add_char buf c;
  1738. ) (vstring s);
  1739. VString (UTF8.Buf.contents buf)
  1740. );
  1741. "utf8_get", Fun2 (fun s p ->
  1742. VInt (UChar.uint_code (try UTF8.get (vstring s) (vint p) with _ -> error()))
  1743. );
  1744. "utf8_iter", Fun2 (fun s f ->
  1745. let ctx = get_ctx() in
  1746. UTF8.iter (fun c ->
  1747. ignore(ctx.do_call VNull f [VInt (UChar.uint_code c)] p);
  1748. ) (vstring s);
  1749. VNull;
  1750. );
  1751. "utf8_compare", Fun2 (fun s1 s2 ->
  1752. VInt (UTF8.compare (vstring s1) (vstring s2))
  1753. );
  1754. (* thread *)
  1755. "thread_create", Fun2 (fun f p ->
  1756. exc (VString "Can't create thread from within a macro");
  1757. );
  1758. "tls_create", Fun0 (fun() ->
  1759. VAbstract (ATls (ref VNull))
  1760. );
  1761. "tls_get", Fun1 (fun t ->
  1762. match t with
  1763. | VAbstract (ATls r) -> !r
  1764. | _ -> error();
  1765. );
  1766. "tls_set", Fun2 (fun t v ->
  1767. match t with
  1768. | VAbstract (ATls r) -> r := v; VNull
  1769. | _ -> error();
  1770. );
  1771. (* lock, mutex, deque : not implemented *)
  1772. (* process *)
  1773. "process_run", (Fun2 (fun p args ->
  1774. match p, args with
  1775. | VString p, VArray args -> VAbstract (AProcess (Process.run p (Array.map vstring args)))
  1776. | _ -> error()
  1777. ));
  1778. "process_stdout_read", (Fun4 (fun p str pos len ->
  1779. match p, str, pos, len with
  1780. | VAbstract (AProcess p), VString str, VInt pos, VInt len -> VInt (Process.read_stdout p str pos len)
  1781. | _ -> error()
  1782. ));
  1783. "process_stderr_read", (Fun4 (fun p str pos len ->
  1784. match p, str, pos, len with
  1785. | VAbstract (AProcess p), VString str, VInt pos, VInt len -> VInt (Process.read_stderr p str pos len)
  1786. | _ -> error()
  1787. ));
  1788. "process_stdin_write", (Fun4 (fun p str pos len ->
  1789. match p, str, pos, len with
  1790. | VAbstract (AProcess p), VString str, VInt pos, VInt len -> VInt (Process.write_stdin p str pos len)
  1791. | _ -> error()
  1792. ));
  1793. "process_stdin_close", (Fun1 (fun p ->
  1794. match p with
  1795. | VAbstract (AProcess p) -> Process.close_stdin p; VNull
  1796. | _ -> error()
  1797. ));
  1798. "process_exit", (Fun1 (fun p ->
  1799. match p with
  1800. | VAbstract (AProcess p) -> VInt (Process.exit p)
  1801. | _ -> error()
  1802. ));
  1803. "process_pid", (Fun1 (fun p ->
  1804. match p with
  1805. | VAbstract (AProcess p) -> VInt (Process.pid p)
  1806. | _ -> error()
  1807. ));
  1808. "process_close", (Fun1 (fun vp ->
  1809. match vp with
  1810. | VAbstract (AProcess p) -> Process.close p; free_abstract vp; VNull
  1811. | _ -> error()
  1812. ));
  1813. (* xml *)
  1814. "parse_xml", (match neko with
  1815. | None -> Fun2 (fun str o ->
  1816. match str, o with
  1817. | VString str, VObject events ->
  1818. let ctx = get_ctx() in
  1819. let p = { psource = "parse_xml"; pline = 0 } in
  1820. let xml = get_field events (hash "xml") in
  1821. let don = get_field events (hash "done") in
  1822. let pcdata = get_field events (hash "pcdata") in
  1823. (*
  1824. Since we use the Xml parser, we don't have support for
  1825. - CDATA
  1826. - comments, prolog, doctype (allowed but skipped)
  1827. let cdata = get_field events (hash "cdata") in
  1828. let comment = get_field events (hash "comment") in
  1829. *)
  1830. let rec loop = function
  1831. | Xml.Element (node, attribs, children) ->
  1832. ignore(ctx.do_call o xml [VString node;VObject (obj (hash_field ctx) (List.map (fun (a,v) -> a, VString v) attribs))] p);
  1833. List.iter loop children;
  1834. ignore(ctx.do_call o don [] p);
  1835. | Xml.PCData s ->
  1836. ignore(ctx.do_call o pcdata [VString s] p);
  1837. in
  1838. let x = XmlParser.make() in
  1839. XmlParser.check_eof x false;
  1840. loop (try
  1841. XmlParser.parse x (XmlParser.SString str)
  1842. with Xml.Error e -> failwith ("Parser failure (" ^ Xml.error e ^ ")")
  1843. | e -> failwith ("Parser failure (" ^ Printexc.to_string e ^ ")"));
  1844. VNull
  1845. | _ -> error())
  1846. | Some neko ->
  1847. let parse_xml = neko.load "std@parse_xml" 2 in
  1848. Fun2 (fun str o -> neko.call parse_xml [str;o])
  1849. );
  1850. (* memory, module : not planned *)
  1851. ]
  1852. (* process *)
  1853. @ (match neko with
  1854. | None -> []
  1855. | Some neko ->
  1856. let win_ec = (try Some (neko.load "std@win_env_changed" 0) with _ -> None) in
  1857. [
  1858. "win_env_changed", (Fun0 (fun() -> match win_ec with None -> error() | Some f -> neko.call f []));
  1859. ]))
  1860. (* ---------------------------------------------------------------------- *)
  1861. (* REGEXP LIBRARY *)
  1862. let reg_lib =
  1863. let error() =
  1864. raise Builtin_error
  1865. in
  1866. (* try to load regexp first : we might fail if pcre is not installed *)
  1867. let neko = (match neko with
  1868. | None -> None
  1869. | Some neko ->
  1870. (try ignore(neko.load "regexp@regexp_new_options" 2); Some neko with _ -> None)
  1871. ) in
  1872. match neko with
  1873. | None ->
  1874. make_library [
  1875. (* regexp_new : deprecated *)
  1876. "regexp_new_options", Fun2 (fun str opt ->
  1877. match str, opt with
  1878. | VString str, VString opt ->
  1879. let case_sensitive = ref true in
  1880. List.iter (function
  1881. | 'm' -> () (* always ON ? *)
  1882. | 'i' -> case_sensitive := false
  1883. | c -> failwith ("Unsupported regexp option '" ^ String.make 1 c ^ "'")
  1884. ) (ExtString.String.explode opt);
  1885. let buf = Buffer.create 0 in
  1886. let rec loop prev esc = function
  1887. | [] -> ()
  1888. | c :: l when esc ->
  1889. (match c with
  1890. | 'n' -> Buffer.add_char buf '\n'
  1891. | 'r' -> Buffer.add_char buf '\r'
  1892. | 't' -> Buffer.add_char buf '\t'
  1893. | 'd' -> Buffer.add_string buf "[0-9]"
  1894. | '\\' -> Buffer.add_string buf "\\\\"
  1895. | '(' | ')' -> Buffer.add_char buf c
  1896. | '1'..'9' | '+' | '$' | '^' | '*' | '?' | '.' | '[' | ']' ->
  1897. Buffer.add_char buf '\\';
  1898. Buffer.add_char buf c;
  1899. | _ -> failwith ("Unsupported escaped char '" ^ String.make 1 c ^ "'"));
  1900. loop c false l
  1901. | c :: l ->
  1902. match c with
  1903. | '\\' -> loop prev true l
  1904. | '(' | '|' | ')' ->
  1905. Buffer.add_char buf '\\';
  1906. Buffer.add_char buf c;
  1907. loop c false l
  1908. | '?' when prev = '(' && (match l with ':' :: _ -> true | _ -> false) ->
  1909. failwith "Non capturing groups '(?:' are not supported in macros"
  1910. | '?' when prev = '*' ->
  1911. failwith "Ungreedy *? are not supported in macros"
  1912. | _ ->
  1913. Buffer.add_char buf c;
  1914. loop c false l
  1915. in
  1916. loop '\000' false (ExtString.String.explode str);
  1917. let str = Buffer.contents buf in
  1918. let r = {
  1919. r = if !case_sensitive then Str.regexp str else Str.regexp_case_fold str;
  1920. r_string = "";
  1921. r_groups = [||];
  1922. } in
  1923. VAbstract (AReg r)
  1924. | _ -> error()
  1925. );
  1926. "regexp_match", Fun4 (fun r str pos len ->
  1927. match r, str, pos, len with
  1928. | VAbstract (AReg r), VString str, VInt pos, VInt len ->
  1929. let nstr, npos, delta = (if len = String.length str - pos then str, pos, 0 else String.sub str pos len, 0, pos) in
  1930. (try
  1931. ignore(Str.search_forward r.r nstr npos);
  1932. let rec loop n =
  1933. if n = 9 then
  1934. []
  1935. else try
  1936. (Some (Str.group_beginning n + delta, Str.group_end n + delta)) :: loop (n + 1)
  1937. with Not_found ->
  1938. None :: loop (n + 1)
  1939. | Invalid_argument _ ->
  1940. []
  1941. in
  1942. r.r_string <- str;
  1943. r.r_groups <- Array.of_list (loop 0);
  1944. VBool true;
  1945. with Not_found ->
  1946. VBool false)
  1947. | _ -> error()
  1948. );
  1949. "regexp_matched", Fun2 (fun r n ->
  1950. match r, n with
  1951. | VAbstract (AReg r), VInt n ->
  1952. (match (try r.r_groups.(n) with _ -> failwith ("Invalid group " ^ string_of_int n)) with
  1953. | None -> VNull
  1954. | Some (pos,pend) -> VString (String.sub r.r_string pos (pend - pos)))
  1955. | _ -> error()
  1956. );
  1957. "regexp_matched_pos", Fun2 (fun r n ->
  1958. match r, n with
  1959. | VAbstract (AReg r), VInt n ->
  1960. (match (try r.r_groups.(n) with _ -> failwith ("Invalid group " ^ string_of_int n)) with
  1961. | None -> VNull
  1962. | Some (pos,pend) -> VObject (obj (hash_field (get_ctx())) ["pos",VInt pos;"len",VInt (pend - pos)]))
  1963. | _ -> error()
  1964. );
  1965. (* regexp_replace : not used by Haxe *)
  1966. (* regexp_replace_all : not used by Haxe *)
  1967. (* regexp_replace_fun : not used by Haxe *)
  1968. ]
  1969. | Some neko ->
  1970. let regexp_new_options = neko.load "regexp@regexp_new_options" 2 in
  1971. let regexp_match = neko.load "regexp@regexp_match" 4 in
  1972. let regexp_matched = neko.load "regexp@regexp_matched" 2 in
  1973. let regexp_matched_pos = neko.load "regexp@regexp_matched_pos" 2 in
  1974. make_library [
  1975. "regexp_new_options", Fun2 (fun str opt -> neko.call regexp_new_options [str;opt]);
  1976. "regexp_match", Fun4 (fun r str pos len -> neko.call regexp_match [r;str;pos;len]);
  1977. "regexp_matched", Fun2 (fun r n -> neko.call regexp_matched [r;n]);
  1978. "regexp_matched_pos", Fun2 (fun r n -> neko.call regexp_matched_pos [r;n]);
  1979. ]
  1980. (* ---------------------------------------------------------------------- *)
  1981. (* ZLIB LIBRARY *)
  1982. let z_lib =
  1983. let error() =
  1984. raise Builtin_error
  1985. in
  1986. make_library [
  1987. "inflate_init", Fun1 (fun f ->
  1988. let z = Extc.zlib_inflate_init2 (match f with VNull -> 15 | VInt i -> i | _ -> error()) in
  1989. VAbstract (AZipI { z = z; z_flush = Extc.Z_NO_FLUSH })
  1990. );
  1991. "deflate_init", Fun1 (fun f ->
  1992. let z = Extc.zlib_deflate_init (match f with VInt i -> i | _ -> error()) in
  1993. VAbstract (AZipD { z = z; z_flush = Extc.Z_NO_FLUSH })
  1994. );
  1995. "deflate_end", Fun1 (fun vz ->
  1996. match vz with
  1997. | VAbstract (AZipD z) -> Extc.zlib_deflate_end z.z; free_abstract vz; VNull;
  1998. | _ -> error()
  1999. );
  2000. "inflate_end", Fun1 (fun vz ->
  2001. match vz with
  2002. | VAbstract (AZipI z) -> Extc.zlib_inflate_end z.z; free_abstract vz; VNull;
  2003. | _ -> error()
  2004. );
  2005. "set_flush_mode", Fun2 (fun z f ->
  2006. match z, f with
  2007. | VAbstract (AZipI z | AZipD z), VString s ->
  2008. z.z_flush <- (match s with
  2009. | "NO" -> Extc.Z_NO_FLUSH
  2010. | "SYNC" -> Extc.Z_SYNC_FLUSH
  2011. | "FULL" -> Extc.Z_FULL_FLUSH
  2012. | "FINISH" -> Extc.Z_FINISH
  2013. | "BLOCK" -> Extc.Z_PARTIAL_FLUSH
  2014. | _ -> error());
  2015. VNull;
  2016. | _ -> error()
  2017. );
  2018. "inflate_buffer", Fun5 (fun z src pos dst dpos ->
  2019. match z, src, pos, dst, dpos with
  2020. | VAbstract (AZipI z), VString src, VInt pos, VString dst, VInt dpos ->
  2021. let r = Extc.zlib_inflate z.z src pos (String.length src - pos) dst dpos (String.length dst - dpos) z.z_flush in
  2022. VObject (obj (hash_field (get_ctx())) [
  2023. "done", VBool r.Extc.z_finish;
  2024. "read", VInt r.Extc.z_read;
  2025. "write", VInt r.Extc.z_wrote;
  2026. ])
  2027. | _ -> error()
  2028. );
  2029. "deflate_buffer", Fun5 (fun z src pos dst dpos ->
  2030. match z, src, pos, dst, dpos with
  2031. | VAbstract (AZipD z), VString src, VInt pos, VString dst, VInt dpos ->
  2032. let r = Extc.zlib_deflate z.z src pos (String.length src - pos) dst dpos (String.length dst - dpos) z.z_flush in
  2033. VObject (obj (hash_field (get_ctx())) [
  2034. "done", VBool r.Extc.z_finish;
  2035. "read", VInt r.Extc.z_read;
  2036. "write", VInt r.Extc.z_wrote;
  2037. ])
  2038. | _ -> error()
  2039. );
  2040. "deflate_bound", Fun2 (fun z size ->
  2041. match z, size with
  2042. | VAbstract (AZipD z), VInt size -> VInt (size + 1024)
  2043. | _ -> error()
  2044. );
  2045. ]
  2046. (* ---------------------------------------------------------------------- *)
  2047. (* MACRO LIBRARY *)
  2048. (* convert float value to haxe expression, handling inf/-inf/nan *)
  2049. let haxe_float f p =
  2050. let std = (Ast.EConst (Ast.Ident "std"), p) in
  2051. let math = (Ast.EField (std, "Math"), p) in
  2052. if (f = infinity) then
  2053. (Ast.EField (math, "POSITIVE_INFINITY"), p)
  2054. else if (f = neg_infinity) then
  2055. (Ast.EField (math, "NEGATIVE_INFINITY"), p)
  2056. else if (f <> f) then
  2057. (Ast.EField (math, "NaN"), p)
  2058. else
  2059. (Ast.EConst (Ast.Float (float_repres f)), p)
  2060. let macro_lib =
  2061. let error() =
  2062. raise Builtin_error
  2063. in
  2064. let ccom() =
  2065. (get_ctx()).curapi.get_com()
  2066. in
  2067. make_library [
  2068. "curpos", Fun0 (fun() -> VAbstract (APos (get_ctx()).curapi.pos));
  2069. "error", Fun2 (fun msg p ->
  2070. match msg, p with
  2071. | VString s, VAbstract (APos p) ->
  2072. (ccom()).Common.error s p;
  2073. raise Abort
  2074. | _ -> error()
  2075. );
  2076. "fatal_error", Fun2 (fun msg p ->
  2077. match msg, p with
  2078. | VString s, VAbstract (APos p) ->
  2079. raise (Typecore.Fatal_error (s,p))
  2080. | _ -> error()
  2081. );
  2082. "warning", Fun2 (fun msg p ->
  2083. match msg, p with
  2084. | VString s, VAbstract (APos p) ->
  2085. (ccom()).warning s p;
  2086. VNull;
  2087. | _ -> error()
  2088. );
  2089. "class_path", Fun0 (fun() ->
  2090. VArray (Array.of_list (List.map (fun s -> VString s) (ccom()).class_path));
  2091. );
  2092. "resolve", Fun1 (fun file ->
  2093. match file with
  2094. | VString s -> VString (try Common.find_file (ccom()) s with Not_found -> failwith ("File not found '" ^ s ^ "'"))
  2095. | _ -> error();
  2096. );
  2097. "define", Fun1 (fun s ->
  2098. match s with
  2099. | VString s -> Common.raw_define (ccom()) s; VNull
  2100. | _ -> error();
  2101. );
  2102. "defined", Fun1 (fun s ->
  2103. match s with
  2104. | VString s -> VBool (Common.raw_defined (ccom()) s)
  2105. | _ -> error();
  2106. );
  2107. "defined_value", Fun1 (fun s ->
  2108. match s with
  2109. | VString s -> (try VString (Common.raw_defined_value (ccom()) s) with Not_found -> VNull)
  2110. | _ -> error();
  2111. );
  2112. "get_defines", Fun0 (fun() ->
  2113. let defines = (ccom()).defines in
  2114. let h = Hashtbl.create 0 in
  2115. PMap.iter (fun n v -> Hashtbl.replace h (VString n) (VString v)) defines;
  2116. enc_hash h
  2117. );
  2118. "get_type", Fun1 (fun s ->
  2119. match s with
  2120. | VString s ->
  2121. (match (get_ctx()).curapi.get_type s with
  2122. | None -> failwith ("Type not found '" ^ s ^ "'")
  2123. | Some t -> encode_type t)
  2124. | _ -> error()
  2125. );
  2126. "get_module", Fun1 (fun s ->
  2127. match s with
  2128. | VString s ->
  2129. enc_array (List.map encode_type ((get_ctx()).curapi.get_module s))
  2130. | _ -> error()
  2131. );
  2132. "on_generate", Fun1 (fun f ->
  2133. match f with
  2134. | VFunction (Fun1 _) ->
  2135. let ctx = get_ctx() in
  2136. ctx.curapi.on_generate (fun tl ->
  2137. ignore(catch_errors ctx (fun() -> ctx.do_call VNull f [enc_array (List.map encode_type tl)] null_pos));
  2138. );
  2139. VNull
  2140. | _ -> error()
  2141. );
  2142. "after_generate", Fun1 (fun f ->
  2143. match f with
  2144. | VFunction (Fun0 _) ->
  2145. let ctx = get_ctx() in
  2146. ctx.curapi.after_generate (fun () ->
  2147. ignore(catch_errors ctx (fun() -> ctx.do_call VNull f [] null_pos));
  2148. );
  2149. VNull
  2150. | _ -> error()
  2151. );
  2152. "on_type_not_found", Fun1 (fun f ->
  2153. match f with
  2154. | VFunction (Fun1 _) ->
  2155. let ctx = get_ctx() in
  2156. ctx.curapi.on_type_not_found (fun path ->
  2157. match catch_errors ctx (fun () -> ctx.do_call VNull f [enc_string path] null_pos) with
  2158. | Some v -> v
  2159. | None -> VNull
  2160. );
  2161. VNull
  2162. | _ -> error()
  2163. );
  2164. "parse", Fun3 (fun s p b ->
  2165. match s, p, b with
  2166. | VString s, VAbstract (APos p), VBool b when s <> "" ->
  2167. (try encode_expr ((get_ctx()).curapi.parse_string s p b) with Invalid_expr -> error())
  2168. | _ -> error()
  2169. );
  2170. "make_expr", Fun2 (fun v p ->
  2171. match p with
  2172. | VAbstract (APos p) ->
  2173. let h_enum = hash "__enum__" and h_et = hash "__et__" and h_ct = hash "__ct__" in
  2174. let h_tag = hash "tag" and h_args = hash "args" in
  2175. let h_length = hash "length" in
  2176. let ctx = get_ctx() in
  2177. let error v = failwith ("Unsupported value " ^ ctx.do_string v) in
  2178. let make_path t =
  2179. let rec loop = function
  2180. | [] -> assert false
  2181. | [name] -> (Ast.EConst (Ast.Ident name),p)
  2182. | name :: l -> (Ast.EField (loop l,name),p)
  2183. in
  2184. let t = t_infos t in
  2185. loop (List.rev (if t.mt_module.m_path = t.mt_path then fst t.mt_path @ [snd t.mt_path] else fst t.mt_module.m_path @ [snd t.mt_module.m_path;snd t.mt_path]))
  2186. in
  2187. let rec loop = function
  2188. | VNull -> (Ast.EConst (Ast.Ident "null"),p)
  2189. | VBool b -> (Ast.EConst (Ast.Ident (if b then "true" else "false")),p)
  2190. | VInt i -> (Ast.EConst (Ast.Int (string_of_int i)),p)
  2191. | VInt32 i -> (Ast.EConst (Ast.Int (Int32.to_string i)),p)
  2192. | VFloat f -> haxe_float f p
  2193. | VAbstract (APos p) ->
  2194. (Ast.EObjectDecl (
  2195. ("fileName" , (Ast.EConst (Ast.String p.Ast.pfile) , p)) ::
  2196. ("lineNumber" , (Ast.EConst (Ast.Int (string_of_int (Lexer.get_error_line p))),p)) ::
  2197. ("className" , (Ast.EConst (Ast.String ("")),p)) ::
  2198. []
  2199. ), p)
  2200. | VString _ | VArray _ | VAbstract _ | VFunction _ | VClosure _ as v -> error v
  2201. | VObject o as v ->
  2202. match o.oproto with
  2203. | None ->
  2204. (match get_field_opt o h_ct with
  2205. | Some (VAbstract (ATDecl t)) ->
  2206. make_path t
  2207. | _ ->
  2208. let fields = List.fold_left (fun acc (fid,v) -> (field_name ctx fid, loop v) :: acc) [] (Array.to_list o.ofields) in
  2209. (Ast.EObjectDecl fields, p))
  2210. | Some proto ->
  2211. match get_field_opt proto h_enum, get_field_opt o h_a, get_field_opt o h_s, get_field_opt o h_length with
  2212. | _, Some (VArray a), _, Some (VInt len) ->
  2213. (Ast.EArrayDecl (List.map loop (Array.to_list (Array.sub a 0 len))),p)
  2214. | _, _, Some (VString s), _ ->
  2215. (Ast.EConst (Ast.String s),p)
  2216. | Some (VObject en), _, _, _ ->
  2217. (match get_field en h_et, get_field o h_tag with
  2218. | VAbstract (ATDecl t), VString tag ->
  2219. let e = (Ast.EField (make_path t,tag),p) in
  2220. (match get_field_opt o h_args with
  2221. | Some (VArray args) ->
  2222. let args = List.map loop (Array.to_list args) in
  2223. (Ast.ECall (e,args),p)
  2224. | _ -> e)
  2225. | _ ->
  2226. error v)
  2227. | _ ->
  2228. error v
  2229. in
  2230. encode_expr (loop v)
  2231. | _ -> error()
  2232. );
  2233. "signature", Fun1 (fun v ->
  2234. let cache = ref [] in
  2235. let cache_count = ref 0 in
  2236. let hfiles = Hashtbl.create 0 in
  2237. let get_file f =
  2238. try
  2239. Hashtbl.find hfiles f
  2240. with Not_found ->
  2241. let ff = Common.unique_full_path f in
  2242. Hashtbl.add hfiles f ff;
  2243. ff
  2244. in
  2245. let do_cache (v:value) (v2:value) =
  2246. (*
  2247. tricky : we need to have a quick not-linear cache based on objects address
  2248. but we can't use address since the GC might be triggered here.
  2249. Instead let's mutate the object temporary.
  2250. *)
  2251. let vt = Obj.repr v in
  2252. let old = Obj.tag vt in
  2253. let old_val = Obj.field vt 0 in
  2254. let abstract_tag = 7 in
  2255. Obj.set_tag vt abstract_tag;
  2256. Obj.set_field vt 0 (Obj.repr (ACacheRef v2));
  2257. cache := (vt,old,old_val) :: !cache;
  2258. incr cache_count
  2259. in
  2260. let rec loop v =
  2261. match v with
  2262. | VNull | VBool _ | VInt _ | VFloat _ | VString _ | VInt32 _ -> v
  2263. | VObject o ->
  2264. let o2 = { ofields = [||]; oproto = None } in
  2265. let v2 = VObject o2 in
  2266. do_cache v v2;
  2267. Array.iter (fun (f,v) -> if f <> h_class then set_field o2 f (loop v)) o.ofields;
  2268. (match o.oproto with
  2269. | None -> ()
  2270. | Some p -> (match loop (VObject p) with VObject p2 -> o2.oproto <- Some p2 | _ -> assert false));
  2271. v2
  2272. | VArray a ->
  2273. let a2 = Array.create (Array.length a) VNull in
  2274. let v2 = VArray a2 in
  2275. do_cache v v2;
  2276. for i = 0 to Array.length a - 1 do
  2277. a2.(i) <- loop a.(i);
  2278. done;
  2279. v2
  2280. | VFunction f ->
  2281. let v2 = VFunction (Obj.magic !cache_count) in
  2282. do_cache v v2;
  2283. v2
  2284. | VClosure (vl,f) ->
  2285. let rl = ref [] in
  2286. let v2 = VClosure (Obj.magic rl, Obj.magic !cache_count) in
  2287. (* in ocaml 4.0+ it was reported some stack overflow, related to vl being GC'ed or mutated in do_cache.
  2288. let's make sure to have a real pointer to it first. The fix will trigger an alloc which might have simply moved the problem away *)
  2289. let vl = VNull :: vl in
  2290. do_cache v v2;
  2291. rl := List.map loop vl;
  2292. v2
  2293. | VAbstract (APos p) -> VAbstract (APos { p with Ast.pfile = get_file p.Ast.pfile })
  2294. | VAbstract (ACacheRef v) -> v
  2295. | VAbstract (AHash h) ->
  2296. let h2 = Hashtbl.create 0 in
  2297. let v2 = VAbstract (AHash h2) in
  2298. do_cache v v2;
  2299. Hashtbl.iter (fun k v -> Hashtbl.add h2 k (loop v)) h2;
  2300. v2
  2301. | VAbstract _ ->
  2302. let v2 = VAbstract (Obj.magic !cache_count) in
  2303. do_cache v v2;
  2304. v2
  2305. in
  2306. let v = loop v in
  2307. (* restore *)
  2308. List.iter (fun (vt,tag,field) ->
  2309. Obj.set_tag vt tag;
  2310. Obj.set_field vt 0 field;
  2311. ) !cache;
  2312. VString (Digest.to_hex (Digest.string (Marshal.to_string v [Marshal.Closures])))
  2313. );
  2314. "to_complex", Fun1 (fun v ->
  2315. try encode_complex_type (make_complex_type (decode_type v))
  2316. with Exit -> VNull
  2317. );
  2318. "unify", Fun2 (fun t1 t2 ->
  2319. let e1 = mk (TObjectDecl []) (decode_type t1) Ast.null_pos in
  2320. try ignore(((get_ctx()).curapi.cast_or_unify) (decode_type t2) e1 Ast.null_pos); VBool true
  2321. with Typecore.Error (Typecore.Unify _,_) -> VBool false
  2322. );
  2323. "typeof", Fun1 (fun v ->
  2324. encode_type ((get_ctx()).curapi.type_expr (decode_expr v)).etype
  2325. );
  2326. "type_expr", Fun1 (fun v ->
  2327. encode_texpr ((get_ctx()).curapi.type_expr (decode_expr v))
  2328. );
  2329. "s_type", Fun1 (fun v ->
  2330. VString (Type.s_type (print_context()) (decode_type v))
  2331. );
  2332. "s_expr", Fun2 (fun v b ->
  2333. let f = match b with VBool true -> Type.s_expr_pretty "" | _ -> Type.s_expr_ast true "" in
  2334. VString (f (Type.s_type (print_context())) (decode_texpr v))
  2335. );
  2336. "is_fmt_string", Fun1 (fun v ->
  2337. match v with
  2338. | VAbstract (APos p) -> VBool(Lexer.is_fmt_string p)
  2339. | _ -> VNull
  2340. );
  2341. "format_string", Fun2 (fun s p ->
  2342. match s,p with
  2343. | VString(s),VAbstract(APos p) -> encode_expr ((get_ctx()).curapi.format_string s p)
  2344. | _ -> VNull
  2345. );
  2346. "display", Fun1 (fun v ->
  2347. match v with
  2348. | VString s ->
  2349. VString ((get_ctx()).curapi.get_display s)
  2350. | _ ->
  2351. error()
  2352. );
  2353. "allow_package", Fun1 (fun v ->
  2354. match v with
  2355. | VString s ->
  2356. (get_ctx()).curapi.allow_package s;
  2357. VNull
  2358. | _ -> error());
  2359. "type_patch", Fun4 (fun t f s v ->
  2360. let p = (get_ctx()).curapi.type_patch in
  2361. (match t, f, s, v with
  2362. | VString t, VString f, VBool s, VString v -> p t f s (Some v)
  2363. | VString t, VString f, VBool s, VNull -> p t f s None
  2364. | _ -> error());
  2365. VNull
  2366. );
  2367. "meta_patch", Fun4 (fun m t f s ->
  2368. let p = (get_ctx()).curapi.meta_patch in
  2369. (match m, t, f, s with
  2370. | VString m, VString t, VString f, VBool s -> p m t (Some f) s
  2371. | VString m, VString t, VNull, VBool s -> p m t None s
  2372. | _ -> error());
  2373. VNull
  2374. );
  2375. "add_global_metadata", Fun5 (fun v1 v2 v3 v4 v5 ->
  2376. match v1,v2,v3,v4,v5 with
  2377. | VString s1,VString s2,VBool b1,VBool b2,VBool b3 ->
  2378. (get_ctx()).curapi.add_global_metadata s1 s2 (b1,b2,b3);
  2379. VNull
  2380. | _ ->
  2381. error()
  2382. );
  2383. "custom_js", Fun1 (fun f ->
  2384. match f with
  2385. | VFunction (Fun1 _) ->
  2386. let ctx = get_ctx() in
  2387. ctx.curapi.set_js_generator (fun api ->
  2388. ignore(catch_errors ctx (fun() -> ctx.do_call VNull f [api] null_pos));
  2389. );
  2390. VNull
  2391. | _ -> error()
  2392. );
  2393. "get_pos_infos", Fun1 (fun p ->
  2394. match p with
  2395. | VAbstract (APos p) -> VObject (obj (hash_field (get_ctx())) ["min",VInt p.Ast.pmin;"max",VInt p.Ast.pmax;"file",VString p.Ast.pfile])
  2396. | _ -> error()
  2397. );
  2398. "make_pos", Fun3 (fun min max file ->
  2399. match min, max, file with
  2400. | VInt min, VInt max, VString file -> VAbstract (APos { Ast.pmin = min; Ast.pmax = max; Ast.pfile = file })
  2401. | _ -> error()
  2402. );
  2403. "add_resource", Fun2 (fun name data ->
  2404. match name, data with
  2405. | VString name, VString data ->
  2406. Hashtbl.replace (ccom()).resources name data;
  2407. let m = (get_ctx()).curapi.current_module() in
  2408. m.m_extra.m_binded_res <- PMap.add name data m.m_extra.m_binded_res;
  2409. VNull
  2410. | _ -> error()
  2411. );
  2412. "get_resources", Fun0 (fun() ->
  2413. let res = (ccom()).resources in
  2414. let h = Hashtbl.create 0 in
  2415. Hashtbl.iter (fun n v -> Hashtbl.replace h (VString n) (VString v)) res;
  2416. enc_hash h
  2417. );
  2418. "local_module", Fun0 (fun() ->
  2419. let m = (get_ctx()).curapi.current_module() in
  2420. VString (Ast.s_type_path m.m_path);
  2421. );
  2422. "local_type", Fun0 (fun() ->
  2423. match (get_ctx()).curapi.get_local_type() with
  2424. | None -> VNull
  2425. | Some t -> encode_type t
  2426. );
  2427. "expected_type", Fun0 (fun() ->
  2428. match (get_ctx()).curapi.get_expected_type() with
  2429. | None -> VNull
  2430. | Some t -> encode_type t
  2431. );
  2432. "call_arguments", Fun0 (fun() ->
  2433. match (get_ctx()).curapi.get_call_arguments() with
  2434. | None -> VNull
  2435. | Some el -> enc_array (List.map encode_expr el)
  2436. );
  2437. "local_method", Fun0 (fun() ->
  2438. VString ((get_ctx()).curapi.get_local_method())
  2439. );
  2440. "local_using", Fun0 (fun() ->
  2441. enc_array (List.map encode_clref ((get_ctx()).curapi.get_local_using()))
  2442. );
  2443. "local_vars", Fun1 (fun as_var ->
  2444. let as_var = match as_var with
  2445. | VNull | VBool false -> false
  2446. | VBool true -> true
  2447. | _ -> error()
  2448. in
  2449. let vars = (get_ctx()).curapi.get_local_vars() in
  2450. let h = Hashtbl.create 0 in
  2451. if as_var then
  2452. PMap.iter (fun n v -> Hashtbl.replace h (VString n) (encode_tvar v)) vars
  2453. else
  2454. PMap.iter (fun n v -> Hashtbl.replace h (VString n) (encode_type v.v_type)) vars;
  2455. enc_hash h
  2456. );
  2457. "follow", Fun2 (fun v once ->
  2458. let t = decode_type v in
  2459. let follow_once t =
  2460. match t with
  2461. | TMono r ->
  2462. (match !r with
  2463. | None -> t
  2464. | Some t -> t)
  2465. | TAbstract _ | TEnum _ | TInst _ | TFun _ | TAnon _ | TDynamic _ ->
  2466. t
  2467. | TType (t,tl) ->
  2468. apply_params t.t_params tl t.t_type
  2469. | TLazy f ->
  2470. (!f)()
  2471. in
  2472. encode_type (match once with VNull | VBool false -> follow t | VBool true -> follow_once t | _ -> error())
  2473. );
  2474. "build_fields", Fun0 (fun() ->
  2475. (get_ctx()).curapi.get_build_fields()
  2476. );
  2477. "define_type", Fun1 (fun v ->
  2478. (get_ctx()).curapi.define_type v;
  2479. VNull
  2480. );
  2481. "define_module", Fun4 (fun p v i u ->
  2482. match p, v, i, u with
  2483. | VString path, VArray vl, VArray ui, VArray ul ->
  2484. (get_ctx()).curapi.define_module path (Array.to_list vl) (List.map decode_import (Array.to_list ui)) (List.map decode_path (Array.to_list ul));
  2485. VNull
  2486. | _ ->
  2487. error()
  2488. );
  2489. "add_class_path", Fun1 (fun v ->
  2490. match v with
  2491. | VString cp ->
  2492. let com = ccom() in
  2493. com.class_path <- (Common.normalize_path cp) :: com.class_path;
  2494. Hashtbl.clear com.file_lookup_cache;
  2495. VNull
  2496. | _ ->
  2497. error()
  2498. );
  2499. "add_native_lib", Fun1 (fun v ->
  2500. match v with
  2501. | VString file ->
  2502. let com = ccom() in
  2503. (match com.platform with
  2504. | Flash -> Genswf.add_swf_lib com file false
  2505. | Java -> Genjava.add_java_lib com file false
  2506. | Cs ->
  2507. let file, is_std = match ExtString.String.nsplit file "@" with
  2508. | [file] ->
  2509. file,false
  2510. | [file;"std"] ->
  2511. file,true
  2512. | _ -> failwith ("unsupported file@`std` format: " ^ file)
  2513. in
  2514. Gencs.add_net_lib com file is_std
  2515. | _ -> failwith "Unsupported platform");
  2516. VNull
  2517. | _ ->
  2518. error()
  2519. );
  2520. "add_native_arg", Fun1 (fun v ->
  2521. match v with
  2522. | VString arg ->
  2523. let com = ccom() in
  2524. (match com.platform with
  2525. | Java | Cs | Cpp ->
  2526. com.c_args <- arg :: com.c_args
  2527. | _ -> failwith "Unsupported platform");
  2528. VNull
  2529. | _ ->
  2530. error()
  2531. );
  2532. "module_dependency", Fun2 (fun m file ->
  2533. match m, file with
  2534. | VString m, VString file ->
  2535. (get_ctx()).curapi.module_dependency m file false;
  2536. VNull
  2537. | _ -> error()
  2538. );
  2539. "module_reuse_call", Fun2 (fun m mcall ->
  2540. match m, mcall with
  2541. | VString m, VString mcall ->
  2542. (get_ctx()).curapi.module_dependency m mcall true;
  2543. VNull
  2544. | _ -> error()
  2545. );
  2546. "get_typed_expr", Fun1 (fun e ->
  2547. let e = decode_texpr e in
  2548. encode_expr (make_ast e)
  2549. );
  2550. "store_typed_expr", Fun1 (fun e ->
  2551. let e = try decode_texpr e with Invalid_expr -> error() in
  2552. encode_expr ((get_ctx()).curapi.store_typed_expr e)
  2553. );
  2554. "get_output", Fun0 (fun() ->
  2555. VString (ccom()).file
  2556. );
  2557. "set_output", Fun1 (fun s ->
  2558. match s with
  2559. | VString s -> (ccom()).file <- s; VNull
  2560. | _ -> error()
  2561. );
  2562. "get_display_pos", Fun0 (fun() ->
  2563. let p = !Parser.resume_display in
  2564. if p = Ast.null_pos then
  2565. VNull
  2566. else
  2567. VObject (obj (hash_field (get_ctx())) ["file",VString p.Ast.pfile;"pos",VInt p.Ast.pmin])
  2568. );
  2569. "pattern_locals", Fun2 (fun e t ->
  2570. let loc = (get_ctx()).curapi.get_pattern_locals (decode_expr e) (decode_type t) in
  2571. let h = Hashtbl.create 0 in
  2572. PMap.iter (fun n (v,_) -> Hashtbl.replace h (VString n) (encode_type v.v_type)) loc;
  2573. enc_hash h
  2574. );
  2575. "macro_context_reused", Fun1 (fun c ->
  2576. match c with
  2577. | VFunction (Fun0 _) ->
  2578. let ctx = get_ctx() in
  2579. ctx.on_reused <- (fun() -> catch_errors ctx (fun() -> ctx.do_call VNull c [] null_pos) = Some (VBool true)) :: ctx.on_reused;
  2580. VNull
  2581. | _ -> error()
  2582. );
  2583. "apply_params", Fun3 (fun tpl tl t ->
  2584. let tpl = List.map (fun v ->
  2585. match v with
  2586. | VObject o ->
  2587. let name = match get_field o (hash "name") with VString s -> s | _ -> assert false in
  2588. let t = decode_type (get_field o (hash "t")) in
  2589. name,t
  2590. | _ -> assert false
  2591. ) (dec_array tpl) in
  2592. let tl = List.map decode_type (dec_array tl) in
  2593. let rec map t = match t with
  2594. | TInst({cl_kind = KTypeParameter _},_) ->
  2595. begin try
  2596. (* use non-physical equality check here to make apply_params work *)
  2597. snd (List.find (fun (_,t2) -> type_iseq t t2) tpl)
  2598. with Not_found ->
  2599. Type.map map t
  2600. end
  2601. | _ -> Type.map map t
  2602. in
  2603. encode_type (apply_params tpl tl (map (decode_type t)))
  2604. );
  2605. ]
  2606. (* ---------------------------------------------------------------------- *)
  2607. (* EVAL *)
  2608. let throw ctx p msg =
  2609. ctx.callstack <- { cpos = p; cthis = ctx.vthis; cstack = DynArray.length ctx.stack; cenv = ctx.venv } :: ctx.callstack;
  2610. exc (VString msg)
  2611. let declare ctx var =
  2612. ctx.locals_map <- PMap.add var ctx.locals_count ctx.locals_map;
  2613. ctx.locals_count <- ctx.locals_count + 1
  2614. let save_locals ctx =
  2615. let old, oldcount = ctx.locals_map, ctx.locals_count in
  2616. (fun() ->
  2617. let n = ctx.locals_count - oldcount in
  2618. ctx.locals_count <- oldcount;
  2619. ctx.locals_map <- old;
  2620. n;
  2621. )
  2622. let get_ident ctx s =
  2623. try
  2624. let index = PMap.find s ctx.locals_map in
  2625. if index >= ctx.locals_barrier then
  2626. AccLocal (ctx.locals_count - index)
  2627. else (try
  2628. AccEnv (DynArray.index_of (fun s2 -> s = s2) ctx.locals_env)
  2629. with Not_found ->
  2630. let index = DynArray.length ctx.locals_env in
  2631. DynArray.add ctx.locals_env s;
  2632. AccEnv index
  2633. )
  2634. with Not_found -> try
  2635. AccGlobal (PMap.find s ctx.globals)
  2636. with Not_found ->
  2637. let g = ref VNull in
  2638. ctx.globals <- PMap.add s g ctx.globals;
  2639. AccGlobal g
  2640. let no_env = [||]
  2641. let rec eval ctx (e,p) =
  2642. match e with
  2643. | EConst c ->
  2644. (match c with
  2645. | True -> (fun() -> VBool true)
  2646. | False -> (fun() -> VBool false)
  2647. | Null -> (fun() -> VNull)
  2648. | This -> (fun() -> ctx.vthis)
  2649. | Int i -> (fun() -> VInt i)
  2650. | Int32 i -> (fun() -> VInt32 i)
  2651. | Float f ->
  2652. let f = float_of_string f in
  2653. (fun() -> VFloat f)
  2654. | String s -> (fun() -> VString s)
  2655. | Builtin "loader" ->
  2656. (fun() -> ctx.loader)
  2657. | Builtin "exports" ->
  2658. (fun() -> ctx.exports)
  2659. | Builtin s ->
  2660. let b = (try Hashtbl.find builtins s with Not_found -> throw ctx p ("Builtin not found '" ^ s ^ "'")) in
  2661. (fun() -> b)
  2662. | Ident s ->
  2663. acc_get ctx p (get_ident ctx s))
  2664. | EBlock el ->
  2665. let old = save_locals ctx in
  2666. let el = List.map (eval ctx) el in
  2667. let n = old() in
  2668. let rec loop = function
  2669. | [] -> VNull
  2670. | [e] -> e()
  2671. | e :: l ->
  2672. ignore(e());
  2673. loop l
  2674. in
  2675. (fun() ->
  2676. let v = loop el in
  2677. pop ctx n;
  2678. v)
  2679. | EParenthesis e ->
  2680. eval ctx e
  2681. | EField (e,f) ->
  2682. let e = eval ctx e in
  2683. let h = hash_field ctx f in
  2684. (fun() ->
  2685. match e() with
  2686. | VObject o -> get_field o h
  2687. | _ -> throw ctx p ("Invalid field access : " ^ f)
  2688. )
  2689. | ECall ((EConst (Builtin "mk_pos"),_),[(ECall (_,[EConst (String file),_]),_);(EConst (Int min),_);(EConst (Int max),_)]) ->
  2690. let pos = VAbstract (APos { Ast.pfile = file; Ast.pmin = min; Ast.pmax = max }) in
  2691. (fun() -> pos)
  2692. | ECall ((EConst (Builtin "typewrap"),_),[t]) ->
  2693. (fun() -> VAbstract (ATDecl (Obj.magic t)))
  2694. | ECall ((EConst (Builtin "delay_call"),_),[EConst (Int index),_]) ->
  2695. let f = ctx.curapi.delayed_macro index in
  2696. let fbuild = ref None in
  2697. let old = { ctx with gen = ctx.gen } in
  2698. let compile_delayed_call() =
  2699. let oldl, oldc, oldb, olde = ctx.locals_map, ctx.locals_count, ctx.locals_barrier, ctx.locals_env in
  2700. ctx.locals_map <- old.locals_map;
  2701. ctx.locals_count <- old.locals_count;
  2702. ctx.locals_barrier <- old.locals_barrier;
  2703. ctx.locals_env <- DynArray.copy old.locals_env;
  2704. let save = save_locals ctx in
  2705. let e = f() in
  2706. let n = save() in
  2707. let e = if DynArray.length ctx.locals_env = DynArray.length old.locals_env then
  2708. e
  2709. else
  2710. let n = DynArray.get ctx.locals_env (DynArray.length ctx.locals_env - 1) in
  2711. (fun() -> exc (VString ("Macro-in-macro call can't access to closure variable '" ^ n ^ "'")))
  2712. in
  2713. ctx.locals_map <- oldl;
  2714. ctx.locals_count <- oldc;
  2715. ctx.locals_barrier <- oldb;
  2716. ctx.locals_env <- olde;
  2717. (fun() ->
  2718. let v = e() in
  2719. pop ctx n;
  2720. v
  2721. )
  2722. in
  2723. (fun() ->
  2724. let e = (match !fbuild with
  2725. | Some e -> e
  2726. | None ->
  2727. let e = compile_delayed_call() in
  2728. fbuild := Some e;
  2729. e
  2730. ) in
  2731. e())
  2732. | ECall (e,el) ->
  2733. let el = List.map (eval ctx) el in
  2734. (match fst e with
  2735. | EField (e,f) ->
  2736. let e = eval ctx e in
  2737. let h = hash_field ctx f in
  2738. (fun() ->
  2739. let pl = List.map (fun f -> f()) el in
  2740. let o = e() in
  2741. let f = (match o with
  2742. | VObject o -> get_field o h
  2743. | _ -> throw ctx p ("Invalid field access : " ^ f)
  2744. ) in
  2745. call ctx o f pl p
  2746. )
  2747. | _ ->
  2748. let e = eval ctx e in
  2749. (fun() ->
  2750. let pl = List.map (fun f -> f()) el in
  2751. call ctx ctx.vthis (e()) pl p
  2752. ))
  2753. | EArray (e1,e2) ->
  2754. let e1 = eval ctx e1 in
  2755. let e2 = eval ctx e2 in
  2756. let acc = AccArray (e1,e2) in
  2757. acc_get ctx p acc
  2758. | EVars vl ->
  2759. let vl = List.map (fun (v,eo) ->
  2760. let eo = (match eo with None -> (fun() -> VNull) | Some e -> eval ctx e) in
  2761. declare ctx v;
  2762. eo
  2763. ) vl in
  2764. (fun() ->
  2765. List.iter (fun e -> push ctx (e())) vl;
  2766. VNull
  2767. )
  2768. | EWhile (econd,e,NormalWhile) ->
  2769. let econd = eval ctx econd in
  2770. let e = eval ctx e in
  2771. let rec loop st =
  2772. match econd() with
  2773. | VBool true ->
  2774. let v = (try
  2775. ignore(e()); None
  2776. with
  2777. | Continue -> pop ctx (DynArray.length ctx.stack - st); None
  2778. | Break v -> pop ctx (DynArray.length ctx.stack - st); Some v
  2779. ) in
  2780. (match v with
  2781. | None -> loop st
  2782. | Some v -> v)
  2783. | _ ->
  2784. VNull
  2785. in
  2786. (fun() -> try loop (DynArray.length ctx.stack) with Sys.Break -> throw ctx p "Ctrl+C")
  2787. | EWhile (econd,e,DoWhile) ->
  2788. let e = eval ctx e in
  2789. let econd = eval ctx econd in
  2790. let rec loop st =
  2791. let v = (try
  2792. ignore(e()); None
  2793. with
  2794. | Continue -> pop ctx (DynArray.length ctx.stack - st); None
  2795. | Break v -> pop ctx (DynArray.length ctx.stack - st); Some v
  2796. ) in
  2797. match v with
  2798. | Some v -> v
  2799. | None ->
  2800. match econd() with
  2801. | VBool true -> loop st
  2802. | _ -> VNull
  2803. in
  2804. (fun() -> loop (DynArray.length ctx.stack))
  2805. | EIf (econd,eif,eelse) ->
  2806. let econd = eval ctx econd in
  2807. let eif = eval ctx eif in
  2808. let eelse = (match eelse with None -> (fun() -> VNull) | Some e -> eval ctx e) in
  2809. (fun() ->
  2810. match econd() with
  2811. | VBool true -> eif()
  2812. | _ -> eelse()
  2813. )
  2814. | ETry (e,exc,ecatch) ->
  2815. let old = save_locals ctx in
  2816. let e = eval ctx e in
  2817. let n1 = old() in
  2818. declare ctx exc;
  2819. let ecatch = eval ctx ecatch in
  2820. let n2 = old() in
  2821. (fun() ->
  2822. let vthis = ctx.vthis in
  2823. let venv = ctx.venv in
  2824. let stack = ctx.callstack in
  2825. let csize = ctx.callsize in
  2826. let size = DynArray.length ctx.stack in
  2827. try
  2828. pop_ret ctx e n1
  2829. with Runtime v ->
  2830. let rec loop n l =
  2831. if n = 0 then List.map (fun s -> s.cpos) l else
  2832. match l with
  2833. | [] -> []
  2834. | _ :: l -> loop (n - 1) l
  2835. in
  2836. ctx.exc <- loop (List.length stack) (List.rev ctx.callstack);
  2837. ctx.callstack <- stack;
  2838. ctx.callsize <- csize;
  2839. ctx.vthis <- vthis;
  2840. ctx.venv <- venv;
  2841. pop ctx (DynArray.length ctx.stack - size);
  2842. push ctx v;
  2843. pop_ret ctx ecatch n2
  2844. )
  2845. | EFunction (pl,e) ->
  2846. let old = save_locals ctx in
  2847. let oldb, oldenv = ctx.locals_barrier, ctx.locals_env in
  2848. ctx.locals_barrier <- ctx.locals_count;
  2849. ctx.locals_env <- DynArray.create();
  2850. List.iter (declare ctx) pl;
  2851. let e = eval ctx e in
  2852. ignore(old());
  2853. let env = ctx.locals_env in
  2854. ctx.locals_barrier <- oldb;
  2855. ctx.locals_env <- oldenv;
  2856. let env = DynArray.to_array (DynArray.map (fun s ->
  2857. acc_get ctx p (get_ident ctx s)) env
  2858. ) in
  2859. let init_env = if Array.length env = 0 then
  2860. (fun() -> no_env)
  2861. else
  2862. (fun() -> Array.map (fun e -> e()) env)
  2863. in
  2864. (match pl with
  2865. | [] ->
  2866. (fun() ->
  2867. let env = init_env() in
  2868. VFunction (Fun0 (fun() ->
  2869. ctx.venv <- env;
  2870. e())))
  2871. | [a] ->
  2872. (fun() ->
  2873. let env = init_env() in
  2874. VFunction (Fun1 (fun v ->
  2875. ctx.venv <- env;
  2876. push ctx v;
  2877. e();
  2878. )))
  2879. | [a;b] ->
  2880. (fun() ->
  2881. let env = init_env() in
  2882. VFunction (Fun2 (fun va vb ->
  2883. ctx.venv <- env;
  2884. push ctx va;
  2885. push ctx vb;
  2886. e();
  2887. )))
  2888. | [a;b;c] ->
  2889. (fun() ->
  2890. let env = init_env() in
  2891. VFunction (Fun3 (fun va vb vc ->
  2892. ctx.venv <- env;
  2893. push ctx va;
  2894. push ctx vb;
  2895. push ctx vc;
  2896. e();
  2897. )))
  2898. | [a;b;c;d] ->
  2899. (fun() ->
  2900. let env = init_env() in
  2901. VFunction (Fun4 (fun va vb vc vd ->
  2902. ctx.venv <- env;
  2903. push ctx va;
  2904. push ctx vb;
  2905. push ctx vc;
  2906. push ctx vd;
  2907. e();
  2908. )))
  2909. | [a;b;c;d;pe] ->
  2910. (fun() ->
  2911. let env = init_env() in
  2912. VFunction (Fun5 (fun va vb vc vd ve ->
  2913. ctx.venv <- env;
  2914. push ctx va;
  2915. push ctx vb;
  2916. push ctx vc;
  2917. push ctx vd;
  2918. push ctx ve;
  2919. e();
  2920. )))
  2921. | _ ->
  2922. (fun() ->
  2923. let env = init_env() in
  2924. VFunction (FunVar (fun vl ->
  2925. if List.length vl != List.length pl then exc (VString "Invalid call");
  2926. ctx.venv <- env;
  2927. List.iter (push ctx) vl;
  2928. e();
  2929. )))
  2930. )
  2931. | EBinop (op,e1,e2) ->
  2932. eval_op ctx op e1 e2 p
  2933. | EReturn None ->
  2934. (fun() -> raise (Return VNull))
  2935. | EReturn (Some e) ->
  2936. let e = eval ctx e in
  2937. (fun() -> raise (Return (e())))
  2938. | EBreak None ->
  2939. (fun() -> raise (Break VNull))
  2940. | EBreak (Some e) ->
  2941. let e = eval ctx e in
  2942. (fun() -> raise (Break (e())))
  2943. | EContinue ->
  2944. (fun() -> raise Continue)
  2945. | ENext (e1,e2) ->
  2946. let e1 = eval ctx e1 in
  2947. let e2 = eval ctx e2 in
  2948. (fun() -> ignore(e1()); e2())
  2949. | EObject fl ->
  2950. let fl = List.map (fun (f,e) -> hash_field ctx f, eval ctx e) fl in
  2951. let fields = Array.of_list (List.map (fun (f,_) -> f,VNull) fl) in
  2952. Array.sort (fun (f1,_) (f2,_) -> compare f1 f2) fields;
  2953. (fun() ->
  2954. let o = {
  2955. ofields = Array.copy fields;
  2956. oproto = None;
  2957. } in
  2958. List.iter (fun (f,e) -> set_field o f (e())) fl;
  2959. VObject o
  2960. )
  2961. | ELabel l ->
  2962. assert false
  2963. | ESwitch (e1,el,eo) ->
  2964. let e1 = eval ctx e1 in
  2965. let el = List.map (fun (cond,e) -> cond, eval ctx cond, eval ctx e) el in
  2966. let eo = (match eo with None -> (fun() -> VNull) | Some e -> eval ctx e) in
  2967. let cases = (try
  2968. let max = ref (-1) in
  2969. let ints = List.map (fun (cond,_,e) ->
  2970. match fst cond with
  2971. | EConst (Int i) -> if i < 0 then raise Exit; if i > !max then max := i; i, e
  2972. | _ -> raise Exit
  2973. ) el in
  2974. let a = Array.create (!max + 1) eo in
  2975. List.iter (fun (i,e) -> a.(i) <- e) (List.rev ints);
  2976. Some a;
  2977. with
  2978. Exit -> None
  2979. ) in
  2980. let def v =
  2981. let rec loop = function
  2982. | [] -> eo()
  2983. | (_,c,e) :: l ->
  2984. if ctx.do_compare v (c()) = CEq then e() else loop l
  2985. in
  2986. loop el
  2987. in
  2988. (match cases with
  2989. | None -> (fun() -> def (e1()))
  2990. | Some t ->
  2991. (fun() ->
  2992. match e1() with
  2993. | VInt i -> if i >= 0 && i < Array.length t then t.(i)() else eo()
  2994. | v -> def v
  2995. ))
  2996. | ENeko _ ->
  2997. throw ctx p "Inline neko code unsupported"
  2998. and eval_oop ctx p o field (params:value list) =
  2999. match get_field_opt o field with
  3000. | None -> None
  3001. | Some f -> Some (call ctx (VObject o) f params p)
  3002. and eval_access ctx (e,p) =
  3003. match e with
  3004. | EField (e,f) ->
  3005. let v = eval ctx e in
  3006. AccField (v,f)
  3007. | EArray (e,eindex) ->
  3008. let v = eval ctx e in
  3009. let idx = eval ctx eindex in
  3010. AccArray (v,idx)
  3011. | EConst (Ident s) ->
  3012. get_ident ctx s
  3013. | EConst This ->
  3014. AccThis
  3015. | _ ->
  3016. throw ctx p "Invalid assign"
  3017. and eval_access_get_set ctx (e,p) =
  3018. match e with
  3019. | EField (e,f) ->
  3020. let v = eval ctx e in
  3021. let cache = ref VNull in
  3022. AccField ((fun() -> cache := v(); !cache),f), AccField((fun() -> !cache), f)
  3023. | EArray (e,eindex) ->
  3024. let v = eval ctx e in
  3025. let idx = eval ctx eindex in
  3026. let vcache = ref VNull and icache = ref VNull in
  3027. AccArray ((fun() -> vcache := v(); !vcache),(fun() -> icache := idx(); !icache)), AccArray ((fun() -> !vcache),(fun() -> !icache))
  3028. | EConst (Ident s) ->
  3029. let acc = get_ident ctx s in
  3030. acc, acc
  3031. | EConst This ->
  3032. AccThis, AccThis
  3033. | _ ->
  3034. throw ctx p "Invalid assign"
  3035. and acc_get ctx p = function
  3036. | AccField (v,f) ->
  3037. let h = hash_field ctx f in
  3038. (fun() ->
  3039. match v() with
  3040. | VObject o -> get_field o h
  3041. | _ -> throw ctx p ("Invalid field access : " ^ f))
  3042. | AccArray (e,index) ->
  3043. (fun() ->
  3044. let e = e() in
  3045. let index = index() in
  3046. (match index, e with
  3047. | VInt i, VArray a -> (try Array.get a i with _ -> VNull)
  3048. | VInt32 _, VArray _ -> VNull
  3049. | _, VObject o ->
  3050. (match eval_oop ctx p o h_get [index] with
  3051. | None -> throw ctx p "Invalid array access"
  3052. | Some v -> v)
  3053. | _ -> throw ctx p "Invalid array access"))
  3054. | AccLocal i ->
  3055. (fun() -> DynArray.get ctx.stack (DynArray.length ctx.stack - i))
  3056. | AccGlobal g ->
  3057. (fun() -> !g)
  3058. | AccThis ->
  3059. (fun() -> ctx.vthis)
  3060. | AccEnv i ->
  3061. (fun() -> ctx.venv.(i))
  3062. and acc_set ctx p acc value =
  3063. match acc with
  3064. | AccField (v,f) ->
  3065. let h = hash_field ctx f in
  3066. (fun() ->
  3067. let v = v() in
  3068. let value = value() in
  3069. match v with
  3070. | VObject o -> set_field o h value; value
  3071. | _ -> throw ctx p ("Invalid field access : " ^ f))
  3072. | AccArray (e,index) ->
  3073. (fun() ->
  3074. let e = e() in
  3075. let index = index() in
  3076. let value = value() in
  3077. (match index, e with
  3078. | VInt i, VArray a -> (try Array.set a i value; value with _ -> value)
  3079. | VInt32 _, VArray _ -> value
  3080. | _, VObject o ->
  3081. (match eval_oop ctx p o h_set [index;value] with
  3082. | None -> throw ctx p "Invalid array access"
  3083. | Some _ -> value);
  3084. | _ -> throw ctx p "Invalid array access"))
  3085. | AccLocal i ->
  3086. (fun() ->
  3087. let value = value() in
  3088. DynArray.set ctx.stack (DynArray.length ctx.stack - i) value;
  3089. value)
  3090. | AccGlobal g ->
  3091. (fun() ->
  3092. let value = value() in
  3093. g := value;
  3094. value)
  3095. | AccThis ->
  3096. (fun() ->
  3097. let value = value() in
  3098. ctx.vthis <- value;
  3099. value)
  3100. | AccEnv i ->
  3101. (fun() ->
  3102. let value = value() in
  3103. ctx.venv.(i) <- value;
  3104. value)
  3105. and number_op ctx p sop iop fop oop rop v1 v2 =
  3106. (fun() ->
  3107. let v1 = v1() in
  3108. let v2 = v2() in
  3109. exc_number_op ctx p sop iop fop oop rop v1 v2)
  3110. and exc_number_op ctx p sop iop fop oop rop v1 v2 =
  3111. match v1, v2 with
  3112. | VInt a, VInt b -> best_int (iop (Int32.of_int a) (Int32.of_int b))
  3113. | VInt32 a, VInt b -> best_int (iop a (Int32.of_int b))
  3114. | VInt a, VInt32 b -> best_int (iop (Int32.of_int a) b)
  3115. | VFloat a, VInt b -> VFloat (fop a (float_of_int b))
  3116. | VFloat a, VInt32 b -> VFloat (fop a (Int32.to_float b))
  3117. | VInt a, VFloat b -> VFloat (fop (float_of_int a) b)
  3118. | VInt32 a, VFloat b -> VFloat (fop (Int32.to_float a) b)
  3119. | VFloat a, VFloat b -> VFloat (fop a b)
  3120. | VInt32 a, VInt32 b -> best_int (iop a b)
  3121. | VObject o, _ ->
  3122. (match eval_oop ctx p o oop [v2] with
  3123. | Some v -> v
  3124. | None ->
  3125. match v2 with
  3126. | VObject o ->
  3127. (match eval_oop ctx p o rop [v1] with
  3128. | Some v -> v
  3129. | None -> throw ctx p sop)
  3130. | _ ->
  3131. throw ctx p sop)
  3132. | _ , VObject o ->
  3133. (match eval_oop ctx p o rop [v1] with
  3134. | Some v -> v
  3135. | None -> throw ctx p sop)
  3136. | _ ->
  3137. throw ctx p sop
  3138. and int_op ctx p op iop v1 v2 =
  3139. (fun() ->
  3140. let v1 = v1() in
  3141. let v2 = v2() in
  3142. match v1, v2 with
  3143. | VInt a, VInt b -> best_int (iop (Int32.of_int a) (Int32.of_int b))
  3144. | VInt32 a, VInt b -> best_int (iop a (Int32.of_int b))
  3145. | VInt a, VInt32 b -> best_int (iop (Int32.of_int a) b)
  3146. | VInt32 a, VInt32 b -> best_int (iop a b)
  3147. | _ -> throw ctx p op)
  3148. and base_op ctx op v1 v2 p =
  3149. match op with
  3150. | "+" ->
  3151. (fun() ->
  3152. let v1 = v1() in
  3153. let v2 = v2() in
  3154. match v1, v2 with
  3155. | (VInt _ | VInt32 _), (VInt _ | VInt32 _) | (VInt _ | VInt32 _), VFloat _ | VFloat _ , (VInt _ | VInt32 _) | VFloat _ , VFloat _ | VObject _ , _ | _ , VObject _ -> exc_number_op ctx p op Int32.add (+.) h_add h_radd v1 v2
  3156. | VString a, _ -> VString (a ^ ctx.do_string v2)
  3157. | _, VString b -> VString (ctx.do_string v1 ^ b)
  3158. | _ -> throw ctx p op)
  3159. | "-" ->
  3160. number_op ctx p op Int32.sub (-.) h_sub h_rsub v1 v2
  3161. | "*" ->
  3162. number_op ctx p op Int32.mul ( *. ) h_mult h_rmult v1 v2
  3163. | "/" ->
  3164. (fun() ->
  3165. let v1 = v1() in
  3166. let v2 = v2() in
  3167. match v1, v2 with
  3168. | VInt i, VInt j -> VFloat ((float_of_int i) /. (float_of_int j))
  3169. | VInt i, VInt32 j -> VFloat ((float_of_int i) /. (Int32.to_float j))
  3170. | VInt32 i, VInt j -> VFloat ((Int32.to_float i) /. (float_of_int j))
  3171. | VInt32 i, VInt32 j -> VFloat ((Int32.to_float i) /. (Int32.to_float j))
  3172. | _ -> exc_number_op ctx p op Int32.div (/.) h_div h_rdiv v1 v2)
  3173. | "%" ->
  3174. number_op ctx p op (fun x y -> if y = 0l then throw ctx p op; Int32.rem x y) mod_float h_mod h_rmod v1 v2
  3175. | "&" ->
  3176. int_op ctx p op Int32.logand v1 v2
  3177. | "|" ->
  3178. int_op ctx p op Int32.logor v1 v2
  3179. | "^" ->
  3180. int_op ctx p op Int32.logxor v1 v2
  3181. | "<<" ->
  3182. int_op ctx p op (fun x y -> Int32.shift_left x (Int32.to_int y)) v1 v2
  3183. | ">>" ->
  3184. int_op ctx p op (fun x y -> Int32.shift_right x (Int32.to_int y)) v1 v2
  3185. | ">>>" ->
  3186. int_op ctx p op (fun x y -> Int32.shift_right_logical x (Int32.to_int y)) v1 v2
  3187. | _ ->
  3188. throw ctx p op
  3189. and eval_op ctx op e1 e2 p =
  3190. match op with
  3191. | "=" ->
  3192. let acc = eval_access ctx e1 in
  3193. let v = eval ctx e2 in
  3194. acc_set ctx p acc v
  3195. | "==" ->
  3196. let v1 = eval ctx e1 in
  3197. let v2 = eval ctx e2 in
  3198. (fun() ->
  3199. let v1 = v1() in
  3200. let v2 = v2() in
  3201. match ctx.do_compare v1 v2 with
  3202. | CEq -> VBool true
  3203. | _ -> VBool false)
  3204. | "!=" ->
  3205. let v1 = eval ctx e1 in
  3206. let v2 = eval ctx e2 in
  3207. (fun() ->
  3208. let v1 = v1() in
  3209. let v2 = v2() in
  3210. match ctx.do_compare v1 v2 with
  3211. | CEq -> VBool false
  3212. | _ -> VBool true)
  3213. | ">" ->
  3214. let v1 = eval ctx e1 in
  3215. let v2 = eval ctx e2 in
  3216. (fun() ->
  3217. let v1 = v1() in
  3218. let v2 = v2() in
  3219. match ctx.do_compare v1 v2 with
  3220. | CSup -> VBool true
  3221. | _ -> VBool false)
  3222. | ">=" ->
  3223. let v1 = eval ctx e1 in
  3224. let v2 = eval ctx e2 in
  3225. (fun() ->
  3226. let v1 = v1() in
  3227. let v2 = v2() in
  3228. match ctx.do_compare v1 v2 with
  3229. | CSup | CEq -> VBool true
  3230. | _ -> VBool false)
  3231. | "<" ->
  3232. let v1 = eval ctx e1 in
  3233. let v2 = eval ctx e2 in
  3234. (fun() ->
  3235. let v1 = v1() in
  3236. let v2 = v2() in
  3237. match ctx.do_compare v1 v2 with
  3238. | CInf -> VBool true
  3239. | _ -> VBool false)
  3240. | "<=" ->
  3241. let v1 = eval ctx e1 in
  3242. let v2 = eval ctx e2 in
  3243. (fun() ->
  3244. let v1 = v1() in
  3245. let v2 = v2() in
  3246. match ctx.do_compare v1 v2 with
  3247. | CInf | CEq -> VBool true
  3248. | _ -> VBool false)
  3249. | "+" | "-" | "*" | "/" | "%" | "|" | "&" | "^" | "<<" | ">>" | ">>>" ->
  3250. let v1 = eval ctx e1 in
  3251. let v2 = eval ctx e2 in
  3252. base_op ctx op v1 v2 p
  3253. | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "&=" | "^=" ->
  3254. let aset, aget = eval_access_get_set ctx e1 in
  3255. let v1 = acc_get ctx p aget in
  3256. let v2 = eval ctx e2 in
  3257. let v = base_op ctx (String.sub op 0 (String.length op - 1)) v1 v2 p in
  3258. acc_set ctx p aset v
  3259. | "&&" ->
  3260. let e1 = eval ctx e1 in
  3261. let e2 = eval ctx e2 in
  3262. (fun() ->
  3263. match e1() with
  3264. | VBool false as v -> v
  3265. | _ -> e2())
  3266. | "||" ->
  3267. let e1 = eval ctx e1 in
  3268. let e2 = eval ctx e2 in
  3269. (fun() ->
  3270. match e1() with
  3271. | VBool true as v -> v
  3272. | _ -> e2())
  3273. | "++=" | "--=" ->
  3274. let aset, aget = eval_access_get_set ctx e1 in
  3275. let v1 = acc_get ctx p aget in
  3276. let v2 = eval ctx e2 in
  3277. let vcache = ref VNull in
  3278. let v = base_op ctx (String.sub op 0 1) (fun() -> vcache := v1(); !vcache) v2 p in
  3279. let set = acc_set ctx p aset v in
  3280. (fun() -> ignore(set()); !vcache)
  3281. | _ ->
  3282. throw ctx p ("Unsupported " ^ op)
  3283. and call ctx vthis vfun pl p =
  3284. let oldthis = ctx.vthis in
  3285. let stackpos = DynArray.length ctx.stack in
  3286. let oldstack = ctx.callstack in
  3287. let oldsize = ctx.callsize in
  3288. let oldenv = ctx.venv in
  3289. ctx.vthis <- vthis;
  3290. ctx.callstack <- { cpos = p; cthis = oldthis; cstack = stackpos; cenv = oldenv } :: ctx.callstack;
  3291. ctx.callsize <- oldsize + 1;
  3292. if oldsize > 600 then exc (VString "Stack overflow");
  3293. let ret = (try
  3294. (match vfun with
  3295. | VClosure (vl,f) ->
  3296. f vl pl
  3297. | VFunction f ->
  3298. (match pl, f with
  3299. | [], Fun0 f -> f()
  3300. | [a], Fun1 f -> f a
  3301. | [a;b], Fun2 f -> f a b
  3302. | [a;b;c], Fun3 f -> f a b c
  3303. | [a;b;c;d], Fun4 f -> f a b c d
  3304. | [a;b;c;d;e], Fun5 f -> f a b c d e
  3305. | _, FunVar f -> f pl
  3306. | _ -> exc (VString (Printf.sprintf "Invalid call (%d args instead of %d)" (List.length pl) (nargs f))))
  3307. | VAbstract (ALazyType f) ->
  3308. encode_type ((!f)())
  3309. | _ ->
  3310. exc (VString "Invalid call"))
  3311. with Return v -> v
  3312. | Stack_overflow -> exc (VString "Compiler Stack overflow")
  3313. | Sys_error msg | Failure msg -> exc (VString msg)
  3314. | Unix.Unix_error (_,cmd,msg) -> exc (VString ("Error " ^ cmd ^ " " ^ msg))
  3315. (* | Invalid_expr -> exc (VString "Invalid input value") *)
  3316. | Builtin_error | Invalid_argument _ -> exc (VString "Invalid call")) in
  3317. ctx.vthis <- oldthis;
  3318. ctx.venv <- oldenv;
  3319. ctx.callstack <- oldstack;
  3320. ctx.callsize <- oldsize;
  3321. pop ctx (DynArray.length ctx.stack - stackpos);
  3322. ret
  3323. (* ---------------------------------------------------------------------- *)
  3324. (* OTHERS *)
  3325. let rec to_string ctx n v =
  3326. if n > 5 then
  3327. "<...>"
  3328. else let n = n + 1 in
  3329. match v with
  3330. | VNull -> "null"
  3331. | VBool true -> "true"
  3332. | VBool false -> "false"
  3333. | VInt i -> string_of_int i
  3334. | VInt32 i -> Int32.to_string i
  3335. | VFloat f ->
  3336. let s = float_repres f in
  3337. let len = String.length s in
  3338. if String.unsafe_get s (len - 1) = '.' then String.sub s 0 (len - 1) else s
  3339. | VString s -> s
  3340. | VArray vl -> "[" ^ String.concat "," (Array.to_list (Array.map (to_string ctx n) vl)) ^ "]"
  3341. | VAbstract a ->
  3342. (match a with
  3343. | APos p -> "#pos(" ^ Lexer.get_error_pos (Printf.sprintf "%s:%d:") p ^ ")"
  3344. | _ -> "#abstract")
  3345. | VFunction f -> "#function:" ^ string_of_int (nargs f)
  3346. | VClosure _ -> "#function:-1"
  3347. | VObject o ->
  3348. match eval_oop ctx null_pos o h_string [] with
  3349. | Some (VString s) -> s
  3350. | _ ->
  3351. let b = Buffer.create 0 in
  3352. let first = ref true in
  3353. Buffer.add_char b '{';
  3354. Array.iter (fun (f,v) ->
  3355. if !first then begin
  3356. Buffer.add_char b ' ';
  3357. first := false;
  3358. end else
  3359. Buffer.add_string b ", ";
  3360. Buffer.add_string b (field_name ctx f);
  3361. Buffer.add_string b " => ";
  3362. Buffer.add_string b (to_string ctx n v);
  3363. ) o.ofields;
  3364. Buffer.add_string b (if !first then "}" else " }");
  3365. Buffer.contents b
  3366. let rec compare ctx a b =
  3367. let fcmp (a:float) b = if a = b then CEq else if a < b then CInf else CSup in
  3368. let scmp (a:string) b = if a = b then CEq else if a < b then CInf else CSup in
  3369. let icmp (a:int32) b = let l = Int32.compare a b in if l = 0 then CEq else if l < 0 then CInf else CSup in
  3370. match a, b with
  3371. | VNull, VNull -> CEq
  3372. | VInt a, VInt b -> if a = b then CEq else if a < b then CInf else CSup
  3373. | VInt32 a, VInt32 b -> icmp a b
  3374. | VInt a, VInt32 b -> icmp (Int32.of_int a) b
  3375. | VInt32 a, VInt b -> icmp a (Int32.of_int b)
  3376. | VFloat a, VFloat b -> fcmp a b
  3377. | VFloat a, VInt b -> fcmp a (float_of_int b)
  3378. | VFloat a, VInt32 b -> fcmp a (Int32.to_float b)
  3379. | VInt a, VFloat b -> fcmp (float_of_int a) b
  3380. | VInt32 a, VFloat b -> fcmp (Int32.to_float a) b
  3381. | VBool a, VBool b -> if a = b then CEq else if a then CSup else CInf
  3382. | VString a, VString b -> scmp a b
  3383. | VInt _ , VString s
  3384. | VInt32 _, VString s
  3385. | VFloat _ , VString s
  3386. | VBool _ , VString s -> scmp (to_string ctx 0 a) s
  3387. | VString s, VInt _
  3388. | VString s, VInt32 _
  3389. | VString s, VFloat _
  3390. | VString s, VBool _ -> scmp s (to_string ctx 0 b)
  3391. | VObject oa, VObject ob ->
  3392. if oa == ob then CEq else
  3393. (match eval_oop ctx null_pos oa h_compare [b] with
  3394. | Some (VInt i) -> if i = 0 then CEq else if i < 0 then CInf else CSup
  3395. | _ -> CUndef)
  3396. | VAbstract a, VAbstract b ->
  3397. if a == b then CEq else CUndef
  3398. | VArray a, VArray b ->
  3399. if a == b then CEq else CUndef
  3400. | VFunction a, VFunction b ->
  3401. if a == b then CEq else CUndef
  3402. | VClosure (la,fa), VClosure (lb,fb) ->
  3403. if la == lb && fa == fb then CEq else CUndef
  3404. | _ ->
  3405. CUndef
  3406. let select ctx =
  3407. get_ctx_ref := (fun() -> ctx)
  3408. let load_prim ctx f n =
  3409. match f, n with
  3410. | VString f, VInt n ->
  3411. let lib, fname = (try ExtString.String.split f "@" with _ -> "", f) in
  3412. (try
  3413. let f = (match lib with
  3414. | "std" -> Hashtbl.find std_lib fname
  3415. | "macro" -> Hashtbl.find macro_lib fname
  3416. | "regexp" -> Hashtbl.find reg_lib fname
  3417. | "zlib" -> Hashtbl.find z_lib fname
  3418. | _ -> failwith ("You cannot use the library '" ^ lib ^ "' inside a macro");
  3419. ) in
  3420. if nargs f <> n then raise Not_found;
  3421. VFunction f
  3422. with Not_found ->
  3423. VFunction (FunVar (fun _ -> exc (VString ("Primitive not found " ^ f ^ ":" ^ string_of_int n)))))
  3424. | _ ->
  3425. exc (VString "Invalid call")
  3426. let create com api =
  3427. let loader = obj hash [
  3428. "args",VArray (Array.of_list (List.map (fun s -> VString s) com.sys_args));
  3429. "loadprim",VFunction (Fun2 (fun a b -> (get_ctx()).do_loadprim a b));
  3430. "loadmodule",VFunction (Fun2 (fun a b -> assert false));
  3431. ] in
  3432. let ctx = {
  3433. gen = Genneko.new_context com 2 true;
  3434. types = Hashtbl.create 0;
  3435. error = false;
  3436. error_proto = { ofields = [||]; oproto = None };
  3437. prototypes = Hashtbl.create 0;
  3438. enums = [||];
  3439. (* eval *)
  3440. locals_map = PMap.empty;
  3441. locals_count = 0;
  3442. locals_barrier = 0;
  3443. locals_env = DynArray.create();
  3444. globals = PMap.empty;
  3445. (* runtime *)
  3446. callstack = [];
  3447. callsize = 0;
  3448. stack = DynArray.create();
  3449. exc = [];
  3450. vthis = VNull;
  3451. venv = [||];
  3452. fields_cache = Hashtbl.copy constants;
  3453. (* api *)
  3454. do_call = Obj.magic();
  3455. do_string = Obj.magic();
  3456. do_loadprim = Obj.magic();
  3457. do_compare = Obj.magic();
  3458. (* context *)
  3459. curapi = api;
  3460. loader = VObject loader;
  3461. on_reused = [];
  3462. is_reused = true;
  3463. exports = VObject { ofields = [||]; oproto = None };
  3464. } in
  3465. ctx.do_call <- call ctx;
  3466. ctx.do_string <- to_string ctx 0;
  3467. ctx.do_loadprim <- load_prim ctx;
  3468. ctx.do_compare <- compare ctx;
  3469. select ctx;
  3470. List.iter (fun e -> ignore((eval ctx e)())) (Genneko.header());
  3471. ctx
  3472. let do_reuse ctx api =
  3473. ctx.is_reused <- false;
  3474. ctx.curapi <- api
  3475. let can_reuse ctx types =
  3476. let has_old_version t =
  3477. let inf = Type.t_infos t in
  3478. try
  3479. Hashtbl.find ctx.types inf.mt_path <> inf.mt_module.m_id
  3480. with Not_found ->
  3481. false
  3482. in
  3483. if List.exists has_old_version types then
  3484. false
  3485. else if ctx.is_reused then
  3486. true
  3487. else if not (List.for_all (fun f -> f()) ctx.on_reused) then
  3488. false
  3489. else begin
  3490. ctx.is_reused <- true;
  3491. true;
  3492. end
  3493. let add_types ctx types ready =
  3494. let types = List.filter (fun t ->
  3495. let path = Type.t_path t in
  3496. if Hashtbl.mem ctx.types path then false else begin
  3497. Hashtbl.add ctx.types path (Type.t_infos t).mt_module.m_id;
  3498. true;
  3499. end
  3500. ) types in
  3501. List.iter ready types;
  3502. let e = (EBlock (Genneko.build ctx.gen types), null_pos) in
  3503. ignore(catch_errors ctx (fun() -> ignore((eval ctx e)())))
  3504. let eval_expr ctx e =
  3505. let e = Genneko.gen_expr ctx.gen e in
  3506. catch_errors ctx (fun() -> (eval ctx e)())
  3507. let get_path ctx path p =
  3508. let rec loop = function
  3509. | [] -> assert false
  3510. | [x] -> (EConst (Ident x),p)
  3511. | x :: l -> (EField (loop l,x),p)
  3512. in
  3513. (eval ctx (loop (List.rev path)))()
  3514. let set_error ctx e =
  3515. ctx.error <- e
  3516. let call_path ctx path f vl api =
  3517. if ctx.error then
  3518. None
  3519. else let old = ctx.curapi in
  3520. ctx.curapi <- api;
  3521. let p = Genneko.pos ctx.gen api.pos in
  3522. catch_errors ctx ~final:(fun() -> ctx.curapi <- old) (fun() ->
  3523. match get_path ctx path p with
  3524. | VObject o ->
  3525. let f = get_field o (hash f) in
  3526. call ctx (VObject o) f vl p
  3527. | _ -> assert false
  3528. )
  3529. (* ---------------------------------------------------------------------- *)
  3530. (* EXPR ENCODING *)
  3531. type enum_index =
  3532. | IExpr
  3533. | IBinop
  3534. | IUnop
  3535. | IConst
  3536. | ITParam
  3537. | ICType
  3538. | IField
  3539. | IType
  3540. | IFieldKind
  3541. | IMethodKind
  3542. | IVarAccess
  3543. | IAccess
  3544. | IClassKind
  3545. | ITypedExpr
  3546. | ITConstant
  3547. | IModuleType
  3548. | IFieldAccess
  3549. | IAnonStatus
  3550. let enum_name = function
  3551. | IExpr -> "ExprDef"
  3552. | IBinop -> "Binop"
  3553. | IUnop -> "Unop"
  3554. | IConst -> "Constant"
  3555. | ITParam -> "TypeParam"
  3556. | ICType -> "ComplexType"
  3557. | IField -> "FieldType"
  3558. | IType -> "Type"
  3559. | IFieldKind -> "FieldKind"
  3560. | IMethodKind -> "MethodKind"
  3561. | IVarAccess -> "VarAccess"
  3562. | IAccess -> "Access"
  3563. | IClassKind -> "ClassKind"
  3564. | ITypedExpr -> "TypedExprDef"
  3565. | ITConstant -> "TConstant"
  3566. | IModuleType -> "ModuleType"
  3567. | IFieldAccess -> "FieldAccess"
  3568. | IAnonStatus -> "AnonStatus"
  3569. let init ctx =
  3570. let enums = [IExpr;IBinop;IUnop;IConst;ITParam;ICType;IField;IType;IFieldKind;IMethodKind;IVarAccess;IAccess;IClassKind;ITypedExpr;ITConstant;IModuleType;IFieldAccess;IAnonStatus] in
  3571. let get_enum_proto e =
  3572. match get_path ctx ["haxe";"macro";enum_name e] null_pos with
  3573. | VObject e ->
  3574. (match get_field e h_constructs with
  3575. | VObject cst ->
  3576. (match get_field cst h_a with
  3577. | VArray a ->
  3578. Array.map (fun s ->
  3579. match s with
  3580. | VObject s -> (match get_field s h_s with VString s -> get_field e (hash s),s | _ -> assert false)
  3581. | _ -> assert false
  3582. ) a
  3583. | _ -> assert false)
  3584. | _ -> assert false)
  3585. | _ -> failwith ("haxe.macro." ^ enum_name e ^ " does not exists")
  3586. in
  3587. ctx.enums <- Array.of_list (List.map get_enum_proto enums);
  3588. ctx.error_proto <- (match get_path ctx ["haxe";"macro";"Error";"prototype"] null_pos with VObject p -> p | _ -> failwith ("haxe.macro.Error does not exists"))
  3589. open Ast
  3590. let null f = function
  3591. | None -> VNull
  3592. | Some v -> f v
  3593. let encode_pos p =
  3594. VAbstract (APos p)
  3595. let enc_inst path fields =
  3596. let ctx = get_ctx() in
  3597. let p = (try Hashtbl.find ctx.prototypes path with Not_found -> try
  3598. (match get_path ctx (path@["prototype"]) Nast.null_pos with
  3599. | VObject o -> Hashtbl.add ctx.prototypes path o; o
  3600. | _ -> raise (Runtime VNull))
  3601. with Runtime _ ->
  3602. failwith ("Prototype not found " ^ String.concat "." path)
  3603. ) in
  3604. let o = obj hash fields in
  3605. o.oproto <- Some p;
  3606. VObject o
  3607. let enc_array l =
  3608. let a = Array.of_list l in
  3609. enc_inst ["Array"] [
  3610. "__a", VArray a;
  3611. "length", VInt (Array.length a);
  3612. ]
  3613. let enc_string s =
  3614. enc_inst ["String"] [
  3615. "__s", VString s;
  3616. "length", VInt (String.length s)
  3617. ]
  3618. let enc_hash h =
  3619. enc_inst ["haxe";"ds";"StringMap"] [
  3620. "h", VAbstract (AHash h);
  3621. ]
  3622. let enc_obj l = VObject (obj hash l)
  3623. let enc_enum (i:enum_index) index pl =
  3624. let eindex : int = Obj.magic i in
  3625. let edef = (get_ctx()).enums.(eindex) in
  3626. if pl = [] then
  3627. fst edef.(index)
  3628. else
  3629. enc_inst ["haxe";"macro";enum_name i] [
  3630. "tag", VString (snd edef.(index));
  3631. "index", VInt index;
  3632. "args", VArray (Array.of_list pl);
  3633. ]
  3634. let compiler_error msg pos =
  3635. exc (enc_inst ["haxe";"macro";"Error"] [("message",enc_string msg);("pos",encode_pos pos)])
  3636. let encode_const c =
  3637. let tag, pl = match c with
  3638. | Int s -> 0, [enc_string s]
  3639. | Float s -> 1, [enc_string s]
  3640. | String s -> 2, [enc_string s]
  3641. | Ident s -> 3, [enc_string s]
  3642. | Regexp (s,opt) -> 4, [enc_string s;enc_string opt]
  3643. in
  3644. enc_enum IConst tag pl
  3645. let rec encode_binop op =
  3646. let tag, pl = match op with
  3647. | OpAdd -> 0, []
  3648. | OpMult -> 1, []
  3649. | OpDiv -> 2, []
  3650. | OpSub -> 3, []
  3651. | OpAssign -> 4, []
  3652. | OpEq -> 5, []
  3653. | OpNotEq -> 6, []
  3654. | OpGt -> 7, []
  3655. | OpGte -> 8, []
  3656. | OpLt -> 9, []
  3657. | OpLte -> 10, []
  3658. | OpAnd -> 11, []
  3659. | OpOr -> 12, []
  3660. | OpXor -> 13, []
  3661. | OpBoolAnd -> 14, []
  3662. | OpBoolOr -> 15, []
  3663. | OpShl -> 16, []
  3664. | OpShr -> 17, []
  3665. | OpUShr -> 18, []
  3666. | OpMod -> 19, []
  3667. | OpAssignOp op -> 20, [encode_binop op]
  3668. | OpInterval -> 21, []
  3669. | OpArrow -> 22, []
  3670. in
  3671. enc_enum IBinop tag pl
  3672. let encode_unop op =
  3673. let tag = match op with
  3674. | Increment -> 0
  3675. | Decrement -> 1
  3676. | Not -> 2
  3677. | Neg -> 3
  3678. | NegBits -> 4
  3679. in
  3680. enc_enum IUnop tag []
  3681. let rec encode_path t =
  3682. let fields = [
  3683. "pack", enc_array (List.map enc_string t.tpackage);
  3684. "name", enc_string t.tname;
  3685. "params", enc_array (List.map encode_tparam t.tparams);
  3686. ] in
  3687. enc_obj (match t.tsub with
  3688. | None -> fields
  3689. | Some s -> ("sub", enc_string s) :: fields)
  3690. and encode_tparam = function
  3691. | TPType t -> enc_enum ITParam 0 [encode_ctype t]
  3692. | TPExpr e -> enc_enum ITParam 1 [encode_expr e]
  3693. and encode_access a =
  3694. let tag = match a with
  3695. | APublic -> 0
  3696. | APrivate -> 1
  3697. | AStatic -> 2
  3698. | AOverride -> 3
  3699. | ADynamic -> 4
  3700. | AInline -> 5
  3701. | AMacro -> 6
  3702. in
  3703. enc_enum IAccess tag []
  3704. and encode_meta_entry (m,ml,p) =
  3705. enc_obj [
  3706. "name", enc_string (fst (MetaInfo.to_string m));
  3707. "params", enc_array (List.map encode_expr ml);
  3708. "pos", encode_pos p;
  3709. ]
  3710. and encode_meta_content m =
  3711. enc_array (List.map encode_meta_entry m)
  3712. and encode_field (f:class_field) =
  3713. let tag, pl = match f.cff_kind with
  3714. | FVar (t,e) -> 0, [null encode_ctype t; null encode_expr e]
  3715. | FFun f -> 1, [encode_fun f]
  3716. | FProp (get,set, t, e) -> 2, [enc_string get; enc_string set; null encode_ctype t; null encode_expr e]
  3717. in
  3718. enc_obj [
  3719. "name",enc_string f.cff_name;
  3720. "doc", null enc_string f.cff_doc;
  3721. "pos", encode_pos f.cff_pos;
  3722. "kind", enc_enum IField tag pl;
  3723. "meta", encode_meta_content f.cff_meta;
  3724. "access", enc_array (List.map encode_access f.cff_access);
  3725. ]
  3726. and encode_ctype t =
  3727. let tag, pl = match t with
  3728. | CTPath p ->
  3729. 0, [encode_path p]
  3730. | CTFunction (pl,r) ->
  3731. 1, [enc_array (List.map encode_ctype pl);encode_ctype r]
  3732. | CTAnonymous fl ->
  3733. 2, [enc_array (List.map encode_field fl)]
  3734. | CTParent t ->
  3735. 3, [encode_ctype t]
  3736. | CTExtend (tl,fields) ->
  3737. 4, [enc_array (List.map encode_path tl); enc_array (List.map encode_field fields)]
  3738. | CTOptional t ->
  3739. 5, [encode_ctype t]
  3740. in
  3741. enc_enum ICType tag pl
  3742. and encode_tparam_decl tp =
  3743. enc_obj [
  3744. "name", enc_string tp.tp_name;
  3745. "params", enc_array (List.map encode_tparam_decl tp.tp_params);
  3746. "constraints", enc_array (List.map encode_ctype tp.tp_constraints);
  3747. ]
  3748. and encode_fun f =
  3749. enc_obj [
  3750. "params", enc_array (List.map encode_tparam_decl f.f_params);
  3751. "args", enc_array (List.map (fun (n,opt,t,e) ->
  3752. enc_obj [
  3753. "name", enc_string n;
  3754. "opt", VBool opt;
  3755. "type", null encode_ctype t;
  3756. "value", null encode_expr e;
  3757. ]
  3758. ) f.f_args);
  3759. "ret", null encode_ctype f.f_type;
  3760. "expr", null encode_expr f.f_expr
  3761. ]
  3762. and encode_expr e =
  3763. let rec loop (e,p) =
  3764. let tag, pl = match e with
  3765. | EConst c ->
  3766. 0, [encode_const c]
  3767. | EArray (e1,e2) ->
  3768. 1, [loop e1;loop e2]
  3769. | EBinop (op,e1,e2) ->
  3770. 2, [encode_binop op;loop e1;loop e2]
  3771. | EField (e,f) ->
  3772. 3, [loop e;enc_string f]
  3773. | EParenthesis e ->
  3774. 4, [loop e]
  3775. | EObjectDecl fl ->
  3776. 5, [enc_array (List.map (fun (f,e) -> enc_obj [
  3777. "field",enc_string f;
  3778. "expr",loop e;
  3779. ]) fl)]
  3780. | EArrayDecl el ->
  3781. 6, [enc_array (List.map loop el)]
  3782. | ECall (e,el) ->
  3783. 7, [loop e;enc_array (List.map loop el)]
  3784. | ENew (p,el) ->
  3785. 8, [encode_path p; enc_array (List.map loop el)]
  3786. | EUnop (op,flag,e) ->
  3787. 9, [encode_unop op; VBool (match flag with Prefix -> false | Postfix -> true); loop e]
  3788. | EVars vl ->
  3789. 10, [enc_array (List.map (fun (v,t,eo) ->
  3790. enc_obj [
  3791. "name",enc_string v;
  3792. "type",null encode_ctype t;
  3793. "expr",null loop eo;
  3794. ]
  3795. ) vl)]
  3796. | EFunction (name,f) ->
  3797. 11, [null enc_string name; encode_fun f]
  3798. | EBlock el ->
  3799. 12, [enc_array (List.map loop el)]
  3800. | EFor (e,eloop) ->
  3801. 13, [loop e;loop eloop]
  3802. | EIn (e1,e2) ->
  3803. 14, [loop e1;loop e2]
  3804. | EIf (econd,e,eelse) ->
  3805. 15, [loop econd;loop e;null loop eelse]
  3806. | EWhile (econd,e,flag) ->
  3807. 16, [loop econd;loop e;VBool (match flag with NormalWhile -> true | DoWhile -> false)]
  3808. | ESwitch (e,cases,eopt) ->
  3809. 17, [loop e;enc_array (List.map (fun (ecl,eg,e) ->
  3810. enc_obj [
  3811. "values",enc_array (List.map loop ecl);
  3812. "guard",null loop eg;
  3813. "expr",null loop e
  3814. ]
  3815. ) cases);null encode_null_expr eopt]
  3816. | ETry (e,catches) ->
  3817. 18, [loop e;enc_array (List.map (fun (v,t,e) ->
  3818. enc_obj [
  3819. "name",enc_string v;
  3820. "type",encode_ctype t;
  3821. "expr",loop e
  3822. ]
  3823. ) catches)]
  3824. | EReturn eo ->
  3825. 19, [null loop eo]
  3826. | EBreak ->
  3827. 20, []
  3828. | EContinue ->
  3829. 21, []
  3830. | EUntyped e ->
  3831. 22, [loop e]
  3832. | EThrow e ->
  3833. 23, [loop e]
  3834. | ECast (e,t) ->
  3835. 24, [loop e; null encode_ctype t]
  3836. | EDisplay (e,flag) ->
  3837. 25, [loop e; VBool flag]
  3838. | EDisplayNew t ->
  3839. 26, [encode_path t]
  3840. | ETernary (econd,e1,e2) ->
  3841. 27, [loop econd;loop e1;loop e2]
  3842. | ECheckType (e,t) ->
  3843. 28, [loop e; encode_ctype t]
  3844. | EMeta (m,e) ->
  3845. 29, [encode_meta_entry m;loop e]
  3846. in
  3847. enc_obj [
  3848. "pos", encode_pos p;
  3849. "expr", enc_enum IExpr tag pl;
  3850. ]
  3851. in
  3852. loop e
  3853. and encode_null_expr e =
  3854. match e with
  3855. | None ->
  3856. enc_obj ["pos", VNull;"expr",VNull]
  3857. | Some e ->
  3858. encode_expr e
  3859. (* ---------------------------------------------------------------------- *)
  3860. (* EXPR DECODING *)
  3861. let opt f v =
  3862. match v with
  3863. | VNull -> None
  3864. | _ -> Some (f v)
  3865. let opt_list f v =
  3866. match v with
  3867. | VNull -> []
  3868. | _ -> f v
  3869. let decode_pos = function
  3870. | VAbstract (APos p) -> p
  3871. | _ -> raise Invalid_expr
  3872. let field v f =
  3873. match v with
  3874. | VObject o -> get_field o (hash f)
  3875. | _ -> raise Invalid_expr
  3876. let decode_enum v =
  3877. match field v "index", field v "args" with
  3878. | VInt i, VNull -> i, []
  3879. | VInt i, VArray a -> i, Array.to_list a
  3880. | _ -> raise Invalid_expr
  3881. let dec_bool = function
  3882. | VBool b -> b
  3883. | _ -> raise Invalid_expr
  3884. let dec_string v =
  3885. match field v "__s" with
  3886. | VString s -> s
  3887. | _ -> raise Invalid_expr
  3888. let dec_array v =
  3889. match field v "__a", field v "length" with
  3890. | VArray a, VInt l -> Array.to_list (if Array.length a = l then a else Array.sub a 0 l)
  3891. | _ -> raise Invalid_expr
  3892. let decode_const c =
  3893. match decode_enum c with
  3894. | 0, [s] -> Int (dec_string s)
  3895. | 1, [s] -> Float (dec_string s)
  3896. | 2, [s] -> String (dec_string s)
  3897. | 3, [s] -> Ident (dec_string s)
  3898. | 4, [s;opt] -> Regexp (dec_string s, dec_string opt)
  3899. | 5, [s] -> Ident (dec_string s) (** deprecated CType, keep until 3.0 release **)
  3900. | _ -> raise Invalid_expr
  3901. let rec decode_op op =
  3902. match decode_enum op with
  3903. | 0, [] -> OpAdd
  3904. | 1, [] -> OpMult
  3905. | 2, [] -> OpDiv
  3906. | 3, [] -> OpSub
  3907. | 4, [] -> OpAssign
  3908. | 5, [] -> OpEq
  3909. | 6, [] -> OpNotEq
  3910. | 7, [] -> OpGt
  3911. | 8, [] -> OpGte
  3912. | 9, [] -> OpLt
  3913. | 10, [] -> OpLte
  3914. | 11, [] -> OpAnd
  3915. | 12, [] -> OpOr
  3916. | 13, [] -> OpXor
  3917. | 14, [] -> OpBoolAnd
  3918. | 15, [] -> OpBoolOr
  3919. | 16, [] -> OpShl
  3920. | 17, [] -> OpShr
  3921. | 18, [] -> OpUShr
  3922. | 19, [] -> OpMod
  3923. | 20, [op] -> OpAssignOp (decode_op op)
  3924. | 21, [] -> OpInterval
  3925. | 22,[] -> OpArrow
  3926. | _ -> raise Invalid_expr
  3927. let decode_unop op =
  3928. match decode_enum op with
  3929. | 0, [] -> Increment
  3930. | 1, [] -> Decrement
  3931. | 2, [] -> Not
  3932. | 3, [] -> Neg
  3933. | 4, [] -> NegBits
  3934. | _ -> raise Invalid_expr
  3935. let decode_import_mode t =
  3936. match decode_enum t with
  3937. | 0, [] -> INormal
  3938. | 1, [alias] -> IAsName (dec_string alias)
  3939. | 2, [] -> IAll
  3940. | _ -> raise Invalid_expr
  3941. let decode_import t = (List.map (fun o -> ((dec_string (field o "name")), (decode_pos (field o "pos")))) (dec_array (field t "path")), decode_import_mode (field t "mode"))
  3942. let rec decode_path t =
  3943. {
  3944. tpackage = List.map dec_string (dec_array (field t "pack"));
  3945. tname = dec_string (field t "name");
  3946. tparams = (match field t "params" with VNull -> [] | a -> List.map decode_tparam (dec_array a));
  3947. tsub = opt dec_string (field t "sub");
  3948. }
  3949. and decode_tparam v =
  3950. match decode_enum v with
  3951. | 0,[t] -> TPType (decode_ctype t)
  3952. | 1,[e] -> TPExpr (decode_expr e)
  3953. | _ -> raise Invalid_expr
  3954. and decode_tparams = function
  3955. | VNull -> []
  3956. | a -> List.map decode_tparam_decl (dec_array a)
  3957. and decode_tparam_decl v =
  3958. {
  3959. tp_name = dec_string (field v "name");
  3960. tp_constraints = (match field v "constraints" with VNull -> [] | a -> List.map decode_ctype (dec_array a));
  3961. tp_params = decode_tparams (field v "params");
  3962. }
  3963. and decode_fun v =
  3964. {
  3965. f_params = decode_tparams (field v "params");
  3966. f_args = List.map (fun o ->
  3967. (dec_string (field o "name"),(match field o "opt" with VNull -> false | v -> dec_bool v),opt decode_ctype (field o "type"),opt decode_expr (field o "value"))
  3968. ) (dec_array (field v "args"));
  3969. f_type = opt decode_ctype (field v "ret");
  3970. f_expr = opt decode_expr (field v "expr");
  3971. }
  3972. and decode_access v =
  3973. match decode_enum v with
  3974. | 0, [] -> APublic
  3975. | 1, [] -> APrivate
  3976. | 2, [] -> AStatic
  3977. | 3, [] -> AOverride
  3978. | 4, [] -> ADynamic
  3979. | 5, [] -> AInline
  3980. | 6, [] -> AMacro
  3981. | _ -> raise Invalid_expr
  3982. and decode_meta_entry v =
  3983. MetaInfo.from_string (dec_string (field v "name")), (match field v "params" with VNull -> [] | a -> List.map decode_expr (dec_array a)), decode_pos (field v "pos")
  3984. and decode_meta_content = function
  3985. | VNull -> []
  3986. | v -> List.map decode_meta_entry (dec_array v)
  3987. and decode_field v =
  3988. let fkind = match decode_enum (field v "kind") with
  3989. | 0, [t;e] ->
  3990. FVar (opt decode_ctype t, opt decode_expr e)
  3991. | 1, [f] ->
  3992. FFun (decode_fun f)
  3993. | 2, [get;set; t; e] ->
  3994. FProp (dec_string get, dec_string set, opt decode_ctype t, opt decode_expr e)
  3995. | _ ->
  3996. raise Invalid_expr
  3997. in
  3998. {
  3999. cff_name = dec_string (field v "name");
  4000. cff_doc = opt dec_string (field v "doc");
  4001. cff_pos = decode_pos (field v "pos");
  4002. cff_kind = fkind;
  4003. cff_access = List.map decode_access (opt_list dec_array (field v "access"));
  4004. cff_meta = opt_list decode_meta_content (field v "meta");
  4005. }
  4006. and decode_ctype t =
  4007. match decode_enum t with
  4008. | 0, [p] ->
  4009. CTPath (decode_path p)
  4010. | 1, [a;r] ->
  4011. CTFunction (List.map decode_ctype (dec_array a), decode_ctype r)
  4012. | 2, [fl] ->
  4013. CTAnonymous (List.map decode_field (dec_array fl))
  4014. | 3, [t] ->
  4015. CTParent (decode_ctype t)
  4016. | 4, [tl;fl] ->
  4017. CTExtend (List.map decode_path (dec_array tl), List.map decode_field (dec_array fl))
  4018. | 5, [t] ->
  4019. CTOptional (decode_ctype t)
  4020. | _ ->
  4021. raise Invalid_expr
  4022. let rec decode_expr v =
  4023. let rec loop v =
  4024. (decode (field v "expr"), decode_pos (field v "pos"))
  4025. and decode e =
  4026. match decode_enum e with
  4027. | 0, [c] ->
  4028. EConst (decode_const c)
  4029. | 1, [e1;e2] ->
  4030. EArray (loop e1, loop e2)
  4031. | 2, [op;e1;e2] ->
  4032. EBinop (decode_op op, loop e1, loop e2)
  4033. | 3, [e;f] ->
  4034. EField (loop e, dec_string f)
  4035. | 4, [e] ->
  4036. EParenthesis (loop e)
  4037. | 5, [a] ->
  4038. EObjectDecl (List.map (fun o ->
  4039. (dec_string (field o "field"), loop (field o "expr"))
  4040. ) (dec_array a))
  4041. | 6, [a] ->
  4042. EArrayDecl (List.map loop (dec_array a))
  4043. | 7, [e;el] ->
  4044. ECall (loop e,List.map loop (dec_array el))
  4045. | 8, [t;el] ->
  4046. ENew (decode_path t,List.map loop (dec_array el))
  4047. | 9, [op;VBool f;e] ->
  4048. EUnop (decode_unop op,(if f then Postfix else Prefix),loop e)
  4049. | 10, [vl] ->
  4050. EVars (List.map (fun v ->
  4051. (dec_string (field v "name"),opt decode_ctype (field v "type"),opt loop (field v "expr"))
  4052. ) (dec_array vl))
  4053. | 11, [fname;f] ->
  4054. EFunction (opt dec_string fname,decode_fun f)
  4055. | 12, [el] ->
  4056. EBlock (List.map loop (dec_array el))
  4057. | 13, [e1;e2] ->
  4058. EFor (loop e1, loop e2)
  4059. | 14, [e1;e2] ->
  4060. EIn (loop e1, loop e2)
  4061. | 15, [e1;e2;e3] ->
  4062. EIf (loop e1, loop e2, opt loop e3)
  4063. | 16, [e1;e2;VBool flag] ->
  4064. EWhile (loop e1,loop e2,if flag then NormalWhile else DoWhile)
  4065. | 17, [e;cases;eo] ->
  4066. let cases = List.map (fun c ->
  4067. (List.map loop (dec_array (field c "values")),opt loop (field c "guard"),opt loop (field c "expr"))
  4068. ) (dec_array cases) in
  4069. ESwitch (loop e,cases,opt decode_null_expr eo)
  4070. | 18, [e;catches] ->
  4071. let catches = List.map (fun c ->
  4072. (dec_string (field c "name"),decode_ctype (field c "type"),loop (field c "expr"))
  4073. ) (dec_array catches) in
  4074. ETry (loop e, catches)
  4075. | 19, [e] ->
  4076. EReturn (opt loop e)
  4077. | 20, [] ->
  4078. EBreak
  4079. | 21, [] ->
  4080. EContinue
  4081. | 22, [e] ->
  4082. EUntyped (loop e)
  4083. | 23, [e] ->
  4084. EThrow (loop e)
  4085. | 24, [e;t] ->
  4086. ECast (loop e,opt decode_ctype t)
  4087. | 25, [e;f] ->
  4088. EDisplay (loop e,dec_bool f)
  4089. | 26, [t] ->
  4090. EDisplayNew (decode_path t)
  4091. | 27, [e1;e2;e3] ->
  4092. ETernary (loop e1,loop e2,loop e3)
  4093. | 28, [e;t] ->
  4094. ECheckType (loop e, decode_ctype t)
  4095. | 29, [m;e] ->
  4096. EMeta (decode_meta_entry m,loop e)
  4097. | 30, [e;f] ->
  4098. EField (loop e, dec_string f) (*** deprecated EType, keep until haxe 3 **)
  4099. | _ ->
  4100. raise Invalid_expr
  4101. in
  4102. try
  4103. loop v
  4104. with Stack_overflow ->
  4105. raise Invalid_expr
  4106. and decode_null_expr v =
  4107. match field v "expr" with
  4108. | VNull -> None
  4109. | _ -> Some (decode_expr v)
  4110. (* ---------------------------------------------------------------------- *)
  4111. (* TYPE ENCODING *)
  4112. let encode_ref v convert tostr =
  4113. enc_obj [
  4114. "get", VFunction (Fun0 (fun() -> convert v));
  4115. "__string", VFunction (Fun0 (fun() -> VString (tostr())));
  4116. "toString", VFunction (Fun0 (fun() -> enc_string (tostr())));
  4117. "$", VAbstract (AUnsafe (Obj.repr v));
  4118. ]
  4119. let decode_ref v : 'a =
  4120. match field v "$" with
  4121. | VAbstract (AUnsafe t) -> Obj.obj t
  4122. | _ -> raise Invalid_expr
  4123. let encode_pmap convert m =
  4124. let h = Hashtbl.create 0 in
  4125. PMap.iter (fun k v -> Hashtbl.add h (VString k) (convert v)) m;
  4126. enc_hash h
  4127. let encode_pmap_array convert m =
  4128. let l = ref [] in
  4129. PMap.iter (fun _ v -> l := !l @ [(convert v)]) m;
  4130. enc_array !l
  4131. let encode_array convert l =
  4132. enc_array (List.map convert l)
  4133. let encode_meta m set =
  4134. let meta = ref m in
  4135. enc_obj [
  4136. "get", VFunction (Fun0 (fun() ->
  4137. encode_meta_content (!meta)
  4138. ));
  4139. "add", VFunction (Fun3 (fun k vl p ->
  4140. (try
  4141. let el = List.map decode_expr (dec_array vl) in
  4142. meta := (MetaInfo.from_string (dec_string k), el, decode_pos p) :: !meta;
  4143. set (!meta)
  4144. with Invalid_expr ->
  4145. failwith "Invalid expression");
  4146. VNull
  4147. ));
  4148. "extract", VFunction (Fun1 (fun k ->
  4149. let k = MetaInfo.from_string (try dec_string k with Invalid_expr -> raise Builtin_error) in
  4150. encode_array encode_meta_entry (List.filter (fun (m,_,_) -> m = k) (!meta))
  4151. ));
  4152. "remove", VFunction (Fun1 (fun k ->
  4153. let k = MetaInfo.from_string (try dec_string k with Invalid_expr -> raise Builtin_error) in
  4154. meta := List.filter (fun (m,_,_) -> m <> k) (!meta);
  4155. set (!meta);
  4156. VNull
  4157. ));
  4158. "has", VFunction (Fun1 (fun k ->
  4159. let k = MetaInfo.from_string (try dec_string k with Invalid_expr -> raise Builtin_error) in
  4160. VBool (List.exists (fun (m,_,_) -> m = k) (!meta));
  4161. ));
  4162. ]
  4163. let rec encode_mtype t fields =
  4164. let i = t_infos t in
  4165. enc_obj ([
  4166. "__t", VAbstract (ATDecl t);
  4167. "pack", enc_array (List.map enc_string (fst i.mt_path));
  4168. "name", enc_string (snd i.mt_path);
  4169. "pos", encode_pos i.mt_pos;
  4170. "module", enc_string (s_type_path i.mt_module.m_path);
  4171. "isPrivate", VBool i.mt_private;
  4172. "meta", encode_meta i.mt_meta (fun m -> i.mt_meta <- m);
  4173. "doc", null enc_string i.mt_doc;
  4174. "params", encode_type_params i.mt_params;
  4175. ] @ fields)
  4176. and encode_type_params tl =
  4177. enc_array (List.map (fun (n,t) -> enc_obj ["name",enc_string n;"t",encode_type t]) tl)
  4178. and encode_tenum e =
  4179. encode_mtype (TEnumDecl e) [
  4180. "isExtern", VBool e.e_extern;
  4181. "exclude", VFunction (Fun0 (fun() -> e.e_extern <- true; VNull));
  4182. "constructs", encode_pmap encode_efield e.e_constrs;
  4183. "names", enc_array (List.map enc_string e.e_names);
  4184. ]
  4185. and encode_tabstract a =
  4186. encode_mtype (TAbstractDecl a) [
  4187. "type", encode_type a.a_this;
  4188. "impl", (match a.a_impl with None -> VNull | Some c -> encode_clref c);
  4189. "binops", enc_array (List.map (fun (op,cf) -> enc_obj [ "op",encode_binop op; "field",encode_cfield cf]) a.a_ops);
  4190. "unops", enc_array (List.map (fun (op,postfix,cf) -> enc_obj [ "op",encode_unop op; "isPostfix",VBool (match postfix with Postfix -> true | Prefix -> false); "field",encode_cfield cf]) a.a_unops);
  4191. "from", enc_array ((List.map (fun t -> enc_obj [ "t",encode_type t; "field",VNull]) a.a_from) @ (List.map (fun (t,cf) -> enc_obj [ "t",encode_type t; "field",encode_cfield cf]) a.a_from_field));
  4192. "to", enc_array ((List.map (fun t -> enc_obj [ "t",encode_type t; "field",VNull]) a.a_to) @ (List.map (fun (t,cf) -> enc_obj [ "t",encode_type t; "field",encode_cfield cf]) a.a_to_field));
  4193. "array", enc_array (List.map encode_cfield a.a_array);
  4194. ]
  4195. and encode_efield f =
  4196. enc_obj [
  4197. "name", enc_string f.ef_name;
  4198. "type", encode_type f.ef_type;
  4199. "pos", encode_pos f.ef_pos;
  4200. "index", VInt f.ef_index;
  4201. "meta", encode_meta f.ef_meta (fun m -> f.ef_meta <- m);
  4202. "doc", null enc_string f.ef_doc;
  4203. "params", encode_type_params f.ef_params;
  4204. ]
  4205. and encode_cfield f =
  4206. enc_obj [
  4207. "name", enc_string f.cf_name;
  4208. "type", (match f.cf_kind with Method _ -> encode_lazy_type f.cf_type | _ -> encode_type f.cf_type);
  4209. "isPublic", VBool f.cf_public;
  4210. "params", encode_type_params f.cf_params;
  4211. "meta", encode_meta f.cf_meta (fun m -> f.cf_meta <- m);
  4212. "expr", (VFunction (Fun0 (fun() -> ignore(follow f.cf_type); (match f.cf_expr with None -> VNull | Some e -> encode_texpr e))));
  4213. "kind", encode_field_kind f.cf_kind;
  4214. "pos", encode_pos f.cf_pos;
  4215. "doc", null enc_string f.cf_doc;
  4216. ]
  4217. and encode_field_kind k =
  4218. let tag, pl = (match k with
  4219. | Type.Var v -> 0, [encode_var_access v.v_read; encode_var_access v.v_write]
  4220. | Method m -> 1, [encode_method_kind m]
  4221. ) in
  4222. enc_enum IFieldKind tag pl
  4223. and encode_var_access a =
  4224. let tag, pl = (match a with
  4225. | AccNormal -> 0, []
  4226. | AccNo -> 1, []
  4227. | AccNever -> 2, []
  4228. | AccResolve -> 3, []
  4229. | AccCall -> 4, []
  4230. | AccInline -> 5, []
  4231. | AccRequire (s,msg) -> 6, [enc_string s; null enc_string msg]
  4232. ) in
  4233. enc_enum IVarAccess tag pl
  4234. and encode_method_kind m =
  4235. let tag, pl = (match m with
  4236. | MethNormal -> 0, []
  4237. | MethInline -> 1, []
  4238. | MethDynamic -> 2, []
  4239. | MethMacro -> 3, []
  4240. ) in
  4241. enc_enum IMethodKind tag pl
  4242. and encode_class_kind k =
  4243. let tag, pl = (match k with
  4244. | KNormal -> 0, []
  4245. | KTypeParameter pl -> 1, [encode_tparams pl]
  4246. | KExtension (cl, params) -> 2, [encode_clref cl; encode_tparams params]
  4247. | KExpr e -> 3, [encode_expr e]
  4248. | KGeneric -> 4, []
  4249. | KGenericInstance (cl, params) -> 5, [encode_clref cl; encode_tparams params]
  4250. | KMacroType -> 6, []
  4251. | KAbstractImpl a -> 7, [encode_abref a]
  4252. | KGenericBuild cfl -> 8, []
  4253. ) in
  4254. enc_enum IClassKind tag pl
  4255. and encode_tclass c =
  4256. ignore(c.cl_build());
  4257. encode_mtype (TClassDecl c) [
  4258. "kind", encode_class_kind c.cl_kind;
  4259. "isExtern", VBool c.cl_extern;
  4260. "exclude", VFunction (Fun0 (fun() -> c.cl_extern <- true; c.cl_init <- None; VNull));
  4261. "isInterface", VBool c.cl_interface;
  4262. "superClass", (match c.cl_super with
  4263. | None -> VNull
  4264. | Some (c,pl) -> enc_obj ["t",encode_clref c;"params",encode_tparams pl]
  4265. );
  4266. "interfaces", enc_array (List.map (fun (c,pl) -> enc_obj ["t",encode_clref c;"params",encode_tparams pl]) c.cl_implements);
  4267. "fields", encode_ref c.cl_ordered_fields (encode_array encode_cfield) (fun() -> "class fields");
  4268. "statics", encode_ref c.cl_ordered_statics (encode_array encode_cfield) (fun() -> "class fields");
  4269. "constructor", (match c.cl_constructor with None -> VNull | Some cf -> encode_cfref cf);
  4270. "init", (match c.cl_init with None -> VNull | Some e -> encode_texpr e);
  4271. "overrides", (enc_array (List.map encode_cfref c.cl_overrides))
  4272. ]
  4273. and encode_ttype t =
  4274. encode_mtype (TTypeDecl t) [
  4275. "isExtern", VBool false;
  4276. "exclude", VFunction (Fun0 (fun() -> VNull));
  4277. "type", encode_type t.t_type;
  4278. ]
  4279. and encode_tanon a =
  4280. enc_obj [
  4281. "fields", encode_pmap_array encode_cfield a.a_fields;
  4282. "status", encode_anon_status !(a.a_status);
  4283. ]
  4284. and encode_anon_status s =
  4285. let tag, pl = (match s with
  4286. | Closed -> 0, []
  4287. | Opened -> 1, []
  4288. | Type.Const -> 2, []
  4289. | Extend tl -> 3, [encode_ref tl (fun tl -> enc_array (List.map encode_type tl)) (fun() -> "<extended types>")]
  4290. | Statics cl -> 4, [encode_clref cl]
  4291. | EnumStatics en -> 5, [encode_enref en]
  4292. | AbstractStatics ab -> 6, [encode_abref ab]
  4293. )
  4294. in
  4295. enc_enum IAnonStatus tag pl
  4296. and encode_tparams pl =
  4297. enc_array (List.map encode_type pl)
  4298. and encode_clref c =
  4299. encode_ref c encode_tclass (fun() -> s_type_path c.cl_path)
  4300. and encode_enref en =
  4301. encode_ref en encode_tenum (fun() -> s_type_path en.e_path)
  4302. and encode_cfref cf =
  4303. encode_ref cf encode_cfield (fun() -> cf.cf_name)
  4304. and encode_abref ab =
  4305. encode_ref ab encode_tabstract (fun() -> s_type_path ab.a_path)
  4306. and encode_type t =
  4307. let rec loop = function
  4308. | TMono r ->
  4309. (match !r with
  4310. | None -> 0, [encode_ref r (fun r -> match !r with None -> VNull | Some t -> encode_type t) (fun() -> "<mono>")]
  4311. | Some t -> loop t)
  4312. | TEnum (e, pl) ->
  4313. 1 , [encode_ref e encode_tenum (fun() -> s_type_path e.e_path); encode_tparams pl]
  4314. | TInst (c, pl) ->
  4315. 2 , [encode_clref c; encode_tparams pl]
  4316. | TType (t,pl) ->
  4317. 3 , [encode_ref t encode_ttype (fun() -> s_type_path t.t_path); encode_tparams pl]
  4318. | TFun (pl,ret) ->
  4319. let pl = List.map (fun (n,o,t) ->
  4320. enc_obj [
  4321. "name",enc_string n;
  4322. "opt",VBool o;
  4323. "t",encode_type t
  4324. ]
  4325. ) pl in
  4326. 4 , [enc_array pl; encode_type ret]
  4327. | TAnon a ->
  4328. 5, [encode_ref a encode_tanon (fun() -> "<anonymous>")]
  4329. | TDynamic tsub as t ->
  4330. if t == t_dynamic then
  4331. 6, [VNull]
  4332. else
  4333. 6, [encode_type tsub]
  4334. | TLazy f ->
  4335. loop (!f())
  4336. | TAbstract (a, pl) ->
  4337. 8, [encode_abref a; encode_tparams pl]
  4338. in
  4339. let tag, pl = loop t in
  4340. enc_enum IType tag pl
  4341. and encode_lazy_type t =
  4342. let rec loop = function
  4343. | TMono r ->
  4344. (match !r with
  4345. | Some t -> loop t
  4346. | _ -> encode_type t)
  4347. | TLazy f ->
  4348. enc_enum IType 7 [VAbstract (ALazyType f)]
  4349. | _ ->
  4350. encode_type t
  4351. in
  4352. loop t
  4353. and decode_type t =
  4354. match decode_enum t with
  4355. | 0, [r] -> TMono (decode_ref r)
  4356. | 1, [e; pl] -> TEnum (decode_ref e, List.map decode_type (dec_array pl))
  4357. | 2, [c; pl] -> TInst (decode_ref c, List.map decode_type (dec_array pl))
  4358. | 3, [t; pl] -> TType (decode_ref t, List.map decode_type (dec_array pl))
  4359. | 4, [pl; r] -> TFun (List.map (fun p -> dec_string (field p "name"), dec_bool (field p "opt"), decode_type (field p "t")) (dec_array pl), decode_type r)
  4360. | 5, [a] -> TAnon (decode_ref a)
  4361. | 6, [VNull] -> t_dynamic
  4362. | 6, [t] -> TDynamic (decode_type t)
  4363. | 7, [VAbstract (ALazyType f)] -> TLazy f
  4364. | 8, [a; pl] -> TAbstract (decode_ref a, List.map decode_type (dec_array pl))
  4365. | _ -> raise Invalid_expr
  4366. let decode_tdecl v =
  4367. match v with
  4368. | VObject o ->
  4369. (match get_field o (hash "__t") with
  4370. | VAbstract (ATDecl t) -> t
  4371. | _ -> raise Invalid_expr)
  4372. | _ -> raise Invalid_expr
  4373. (* ---------------------------------------------------------------------- *)
  4374. (* TEXPR Encoding *)
  4375. let vopt f v = match v with
  4376. | None -> VNull
  4377. | Some v -> f v
  4378. let rec encode_tconst c =
  4379. let tag, pl = match c with
  4380. | TInt i -> 0,[best_int i]
  4381. | TFloat f -> 1,[enc_string f]
  4382. | TString s -> 2,[enc_string s]
  4383. | TBool b -> 3,[VBool b]
  4384. | TNull -> 4,[]
  4385. | TThis -> 5,[]
  4386. | TSuper -> 6,[]
  4387. in
  4388. enc_enum ITConstant tag pl
  4389. and encode_tvar v =
  4390. let f_extra (pl,e) =
  4391. enc_obj [
  4392. "params",encode_type_params pl;
  4393. "expr",vopt encode_texpr e
  4394. ]
  4395. in
  4396. enc_obj [
  4397. "id", VInt v.v_id;
  4398. "name", enc_string v.v_name;
  4399. "t", encode_type v.v_type;
  4400. "capture", VBool v.v_capture;
  4401. "extra", vopt f_extra v.v_extra;
  4402. "meta", encode_meta_content v.v_meta;
  4403. "$", VAbstract (AUnsafe (Obj.repr v));
  4404. ]
  4405. and encode_module_type mt =
  4406. let tag,pl = match mt with
  4407. | TClassDecl c -> 0,[encode_clref c]
  4408. | TEnumDecl e -> 1,[encode_enref e]
  4409. | TTypeDecl t -> 2,[encode_ref t encode_ttype (fun () -> s_type_path t.t_path)]
  4410. | TAbstractDecl a -> 3,[encode_abref a]
  4411. in
  4412. enc_enum IModuleType tag pl
  4413. and encode_tfunc func =
  4414. enc_obj [
  4415. "args",enc_array (List.map (fun (v,c) ->
  4416. enc_obj [
  4417. "v",encode_tvar v;
  4418. "value",match c with None -> VNull | Some c -> encode_tconst c
  4419. ]
  4420. ) func.tf_args);
  4421. "t",encode_type func.tf_type;
  4422. "expr",encode_texpr func.tf_expr
  4423. ]
  4424. and encode_field_access fa =
  4425. let tag,pl = match fa with
  4426. | FInstance(c,_,cf) -> 0,[encode_clref c;encode_cfref cf] (* TODO: breaking change, kind of *)
  4427. | FStatic(c,cf) -> 1,[encode_clref c;encode_cfref cf]
  4428. | FAnon(cf) -> 2,[encode_cfref cf]
  4429. | FDynamic(s) -> 3,[enc_string s]
  4430. | FClosure(co,cf) -> 4,[(match co with Some (c,_) -> encode_clref c | None -> VNull);encode_cfref cf] (* TODO: breaking change, kind of, too *)
  4431. | FEnum(en,ef) -> 5,[encode_enref en;encode_efield ef]
  4432. in
  4433. enc_enum IFieldAccess tag pl
  4434. and encode_texpr e =
  4435. let rec loop e =
  4436. let tag, pl = match e.eexpr with
  4437. | TConst c -> 0,[encode_tconst c]
  4438. | TLocal v -> 1,[encode_tvar v]
  4439. | TArray(e1,e2) -> 2,[loop e1; loop e2]
  4440. | TBinop(op,e1,e2) -> 3,[encode_binop op;loop e1;loop e2]
  4441. | TField(e1,fa) -> 4,[loop e1;encode_field_access fa]
  4442. | TTypeExpr mt -> 5,[encode_module_type mt]
  4443. | TParenthesis e1 -> 6,[loop e1]
  4444. | TObjectDecl fl -> 7, [enc_array (List.map (fun (f,e) ->
  4445. enc_obj [
  4446. "name",enc_string f;
  4447. "expr",loop e;
  4448. ]) fl)]
  4449. | TArrayDecl el -> 8,[encode_texpr_list el]
  4450. | TCall(e1,el) -> 9,[loop e1;encode_texpr_list el]
  4451. | TNew(c,pl,el) -> 10,[encode_clref c;encode_tparams pl;encode_texpr_list el]
  4452. | TUnop(op,flag,e1) -> 11,[encode_unop op;VBool (flag = Postfix);loop e1]
  4453. | TFunction func -> 12,[encode_tfunc func]
  4454. | TVar (v,eo) -> 13,[encode_tvar v;vopt encode_texpr eo]
  4455. | TBlock el -> 14,[encode_texpr_list el]
  4456. | TFor(v,e1,e2) -> 15,[encode_tvar v;loop e1;loop e2]
  4457. | TIf(eif,ethen,eelse) -> 16,[loop eif;loop ethen;vopt encode_texpr eelse]
  4458. | TWhile(econd,e1,flag) -> 17,[loop econd;loop e1;VBool (flag = NormalWhile)]
  4459. | TSwitch(e1,cases,edef) -> 18,[
  4460. loop e1;
  4461. enc_array (List.map (fun (el,e) -> enc_obj ["values",encode_texpr_list el;"expr",loop e]) cases);
  4462. vopt encode_texpr edef
  4463. ]
  4464. | TTry(e1,catches) -> 19,[
  4465. loop e1;
  4466. enc_array (List.map (fun (v,e) ->
  4467. enc_obj [
  4468. "v",encode_tvar v;
  4469. "expr",loop e
  4470. ]) catches
  4471. )]
  4472. | TReturn e1 -> 20,[vopt encode_texpr e1]
  4473. | TBreak -> 21,[]
  4474. | TContinue -> 22,[]
  4475. | TThrow e1 -> 23,[loop e1]
  4476. | TCast(e1,mt) -> 24,[loop e1;match mt with None -> VNull | Some mt -> encode_module_type mt]
  4477. | TMeta(m,e1) -> 25,[encode_meta_entry m;loop e1]
  4478. | TEnumParameter(e1,ef,i) -> 26,[loop e1;encode_efield ef;VInt i]
  4479. in
  4480. enc_obj [
  4481. "pos", encode_pos e.epos;
  4482. "expr", enc_enum ITypedExpr tag pl;
  4483. "t", encode_type e.etype
  4484. ]
  4485. in
  4486. loop e
  4487. and encode_texpr_list el =
  4488. enc_array (List.map encode_texpr el)
  4489. (* ---------------------------------------------------------------------- *)
  4490. (* TEXPR Decoding *)
  4491. let decode_tconst c =
  4492. match decode_enum c with
  4493. | 0, [s] -> TInt (match s with VInt i -> Int32.of_int i | VInt32 i -> i | _ -> raise Invalid_expr)
  4494. | 1, [s] -> TFloat (dec_string s)
  4495. | 2, [s] -> TString (dec_string s)
  4496. | 3, [s] -> TBool (dec_bool s)
  4497. | 4, [] -> TNull
  4498. | 5, [] -> TThis
  4499. | 6, [] -> TSuper
  4500. | _ -> raise Invalid_expr
  4501. let decode_type_params v =
  4502. List.map (fun v -> dec_string (field v "name"),decode_type (field v "t")) (dec_array v)
  4503. let decode_tvar v =
  4504. match field v "$" with
  4505. | VAbstract (AUnsafe t) -> Obj.obj t
  4506. | _ -> raise Invalid_expr
  4507. let decode_var_access v =
  4508. match decode_enum v with
  4509. | 0, [] -> AccNormal
  4510. | 1, [] -> AccNo
  4511. | 2, [] -> AccNever
  4512. | 3, [] -> AccResolve
  4513. | 4, [] -> AccCall
  4514. | 5, [] -> AccInline
  4515. | 6, [s1;s2] -> AccRequire(dec_string s1, opt dec_string s2)
  4516. | _ -> raise Invalid_expr
  4517. let decode_method_kind v =
  4518. match decode_enum v with
  4519. | 0, [] -> MethNormal
  4520. | 1, [] -> MethInline
  4521. | 2, [] -> MethDynamic
  4522. | 3, [] -> MethMacro
  4523. | _ -> raise Invalid_expr
  4524. let decode_field_kind v =
  4525. match decode_enum v with
  4526. | 0, [vr;vw] -> Type.Var({v_read = decode_var_access vr; v_write = decode_var_access vw})
  4527. | 1, [m] -> Method (decode_method_kind m)
  4528. | _ -> raise Invalid_expr
  4529. let decode_cfield v =
  4530. {
  4531. cf_name = dec_string (field v "name");
  4532. cf_type = decode_type (field v "type");
  4533. cf_public = dec_bool (field v "isPublic");
  4534. cf_pos = decode_pos (field v "pos");
  4535. cf_doc = opt dec_string (field v "doc");
  4536. cf_meta = []; (* TODO *)
  4537. cf_kind = decode_field_kind (field v "kind");
  4538. cf_params = decode_type_params (field v "params");
  4539. cf_expr = None;
  4540. cf_overloads = [];
  4541. }
  4542. let decode_efield v =
  4543. {
  4544. ef_name = dec_string (field v "name");
  4545. ef_type = decode_type (field v "type");
  4546. ef_pos = decode_pos (field v "pos");
  4547. ef_index = (match field v "index" with VInt i -> i | _ -> raise Invalid_expr);
  4548. ef_meta = []; (* TODO *)
  4549. ef_doc = opt dec_string (field v "doc");
  4550. ef_params = decode_type_params (field v "params")
  4551. }
  4552. let decode_field_access v =
  4553. match decode_enum v with
  4554. | 0, [c;cf] ->
  4555. let c = decode_ref c in
  4556. FInstance(c,List.map snd c.cl_params,decode_ref cf) (* TODO: breaking change? *)
  4557. | 1, [c;cf] -> FStatic(decode_ref c,decode_ref cf)
  4558. | 2, [cf] -> FAnon(decode_ref cf)
  4559. | 3, [s] -> FDynamic(dec_string s)
  4560. | 4, [co;cf] -> FClosure(opt decode_ref co,decode_ref cf)
  4561. | 5, [e;ef] -> FEnum(decode_ref e,decode_efield ef)
  4562. | _ -> raise Invalid_expr
  4563. let decode_module_type v =
  4564. match decode_enum v with
  4565. | 0, [c] -> TClassDecl (decode_ref c)
  4566. | 1, [en] -> TEnumDecl (decode_ref en)
  4567. | 2, [t] -> TTypeDecl (decode_ref t)
  4568. | 3, [a] -> TAbstractDecl (decode_ref a)
  4569. | _ -> raise Invalid_expr
  4570. let decode_tfunc v =
  4571. {
  4572. tf_args = List.map (fun v -> decode_tvar (field v "v"),opt decode_tconst (field v "value")) (dec_array (field v "args"));
  4573. tf_type = decode_type (field v "t");
  4574. tf_expr = decode_texpr (field v "expr")
  4575. }
  4576. let rec decode_texpr v =
  4577. let rec loop v =
  4578. mk (decode (field v "expr")) (decode_type (field v "t")) (decode_pos (field v "pos"))
  4579. and decode e =
  4580. match decode_enum e with
  4581. | 0, [c] -> TConst(decode_tconst c)
  4582. | 1, [v] -> TLocal(decode_tvar v)
  4583. | 2, [v1;v2] -> TArray(loop v1,loop v2)
  4584. | 3, [op;v1;v2] -> TBinop(decode_op op,loop v1,loop v2)
  4585. | 4, [v1;fa] -> TField(loop v1,decode_field_access fa)
  4586. | 5, [mt] -> TTypeExpr(decode_module_type mt)
  4587. | 6, [v1] -> TParenthesis(loop v1)
  4588. | 7, [v] -> TObjectDecl(List.map (fun v -> dec_string (field v "name"),loop (field v "expr")) (dec_array v))
  4589. | 8, [vl] -> TArrayDecl(List.map loop (dec_array vl))
  4590. | 9, [v1;vl] -> TCall(loop v1,List.map loop (dec_array vl))
  4591. | 10, [c;tl;vl] -> TNew(decode_ref c,List.map decode_type (dec_array tl),List.map loop (dec_array vl))
  4592. | 11, [op;pf;v1] -> TUnop(decode_unop op,(if dec_bool pf then Postfix else Prefix),loop v1)
  4593. | 12, [f] -> TFunction(decode_tfunc f)
  4594. | 13, [v;eo] -> TVar(decode_tvar v,opt loop eo)
  4595. | 14, [vl] -> TBlock(List.map loop (dec_array vl))
  4596. | 15, [v;v1;v2] -> TFor(decode_tvar v,loop v1,loop v2)
  4597. | 16, [vif;vthen;velse] -> TIf(loop vif,loop vthen,opt loop velse)
  4598. | 17, [vcond;v1;b] -> TWhile(loop vcond,loop v1,if dec_bool b then NormalWhile else DoWhile)
  4599. | 18, [v1;cl;vdef] -> TSwitch(loop v1,List.map (fun v -> List.map loop (dec_array (field v "values")),loop (field v "expr")) (dec_array cl),opt loop vdef)
  4600. | 19, [v1;cl] -> TTry(loop v1,List.map (fun v -> decode_tvar (field v "v"),loop (field v "expr")) (dec_array cl))
  4601. | 20, [vo] -> TReturn(opt loop vo)
  4602. | 21, [] -> TBreak
  4603. | 22, [] -> TContinue
  4604. | 23, [v1] -> TThrow(loop v1)
  4605. | 24, [v1;mto] -> TCast(loop v1,opt decode_module_type mto)
  4606. | 25, [m;v1] -> TMeta(decode_meta_entry m,loop v1)
  4607. | 26, [v1;ef;i] -> TEnumParameter(loop v1,decode_efield ef,match i with VInt i -> i | _ -> raise Invalid_expr)
  4608. | i,el -> Printf.printf "%i %i\n" i (List.length el); raise Invalid_expr
  4609. in
  4610. try
  4611. loop v
  4612. with Stack_overflow ->
  4613. raise Invalid_expr
  4614. (* ---------------------------------------------------------------------- *)
  4615. (* TYPE DEFINITION *)
  4616. let decode_type_def v =
  4617. let pack = List.map dec_string (dec_array (field v "pack")) in
  4618. let name = dec_string (field v "name") in
  4619. let meta = decode_meta_content (field v "meta") in
  4620. let pos = decode_pos (field v "pos") in
  4621. let isExtern = (match field v "isExtern" with VNull -> false | v -> dec_bool v) in
  4622. let fields = List.map decode_field (dec_array (field v "fields")) in
  4623. let mk fl dl =
  4624. {
  4625. d_name = name;
  4626. d_doc = None;
  4627. d_params = decode_tparams (field v "params");
  4628. d_meta = meta;
  4629. d_flags = fl;
  4630. d_data = dl;
  4631. }
  4632. in
  4633. let tdef = (match decode_enum (field v "kind") with
  4634. | 0, [] ->
  4635. let conv f =
  4636. let loop (n,opt,t,_) =
  4637. match t with
  4638. | None -> raise Invalid_expr
  4639. | Some t -> n, opt, t
  4640. in
  4641. let args, params, t = (match f.cff_kind with
  4642. | FVar (t,None) -> [], [], t
  4643. | FFun f -> List.map loop f.f_args, f.f_params, f.f_type
  4644. | _ -> raise Invalid_expr
  4645. ) in
  4646. {
  4647. ec_name = f.cff_name;
  4648. ec_doc = f.cff_doc;
  4649. ec_meta = f.cff_meta;
  4650. ec_pos = f.cff_pos;
  4651. ec_args = args;
  4652. ec_params = params;
  4653. ec_type = t;
  4654. }
  4655. in
  4656. EEnum (mk (if isExtern then [EExtern] else []) (List.map conv fields))
  4657. | 1, [] ->
  4658. ETypedef (mk (if isExtern then [EExtern] else []) (CTAnonymous fields))
  4659. | 2, [ext;impl;interf] ->
  4660. let flags = if isExtern then [HExtern] else [] in
  4661. let flags = (match interf with VNull | VBool false -> flags | VBool true -> HInterface :: flags | _ -> raise Invalid_expr) in
  4662. let flags = (match opt decode_path ext with None -> flags | Some t -> HExtends t :: flags) in
  4663. let flags = (match opt (fun v -> List.map decode_path (dec_array v)) impl with None -> flags | Some l -> List.map (fun t -> HImplements t) l @ flags) in
  4664. EClass (mk flags fields)
  4665. | 3, [t] ->
  4666. ETypedef (mk (if isExtern then [EExtern] else []) (decode_ctype t))
  4667. | 4, [tthis;tfrom;tto] ->
  4668. let flags = match opt dec_array tfrom with None -> [] | Some ta -> List.map (fun t -> AFromType (decode_ctype t)) ta in
  4669. let flags = match opt dec_array tto with None -> flags | Some ta -> (List.map (fun t -> AToType (decode_ctype t)) ta) @ flags in
  4670. let flags = match opt decode_ctype tthis with None -> flags | Some t -> (AIsType t) :: flags in
  4671. EAbstract(mk flags fields)
  4672. | _ ->
  4673. raise Invalid_expr
  4674. ) in
  4675. (* if our package ends with an uppercase letter, then it's the module name *)
  4676. let pack,name = (match List.rev pack with
  4677. | last :: l when not (is_lower_ident last) -> List.rev l, last
  4678. | _ -> pack, name
  4679. ) in
  4680. (pack, name), tdef, pos
  4681. (* ---------------------------------------------------------------------- *)
  4682. (* VALUE-TO-CONSTANT *)
  4683. let rec make_const e =
  4684. match e.eexpr with
  4685. | TConst c ->
  4686. (match c with
  4687. | TInt i -> best_int i
  4688. | TFloat s -> VFloat (float_of_string s)
  4689. | TString s -> enc_string s
  4690. | TBool b -> VBool b
  4691. | TNull -> VNull
  4692. | TThis | TSuper -> raise Exit)
  4693. | TParenthesis e | TMeta(_,e) ->
  4694. make_const e
  4695. | TObjectDecl el ->
  4696. VObject (obj (hash_field (get_ctx())) (List.map (fun (f,e) -> f, make_const e) el))
  4697. | TArrayDecl al ->
  4698. enc_array (List.map make_const al)
  4699. | _ ->
  4700. raise Exit
  4701. (* ---------------------------------------------------------------------- *)
  4702. (* TEXPR-TO-AST-EXPR *)
  4703. open Ast
  4704. let tpath p mp pl =
  4705. if snd mp = snd p then
  4706. CTPath {
  4707. tpackage = fst p;
  4708. tname = snd p;
  4709. tparams = List.map (fun t -> TPType t) pl;
  4710. tsub = None;
  4711. }
  4712. else CTPath {
  4713. tpackage = fst mp;
  4714. tname = snd mp;
  4715. tparams = List.map (fun t -> TPType t) pl;
  4716. tsub = Some (snd p);
  4717. }
  4718. let rec make_type = function
  4719. | TMono r ->
  4720. (match !r with
  4721. | None -> raise Exit
  4722. | Some t -> make_type t)
  4723. | TEnum (e,pl) ->
  4724. tpath e.e_path e.e_module.m_path (List.map make_type pl)
  4725. | TInst({cl_kind = KTypeParameter _} as c,pl) ->
  4726. tpath ([],snd c.cl_path) ([],snd c.cl_path) (List.map make_type pl)
  4727. | TInst (c,pl) ->
  4728. tpath c.cl_path c.cl_module.m_path (List.map make_type pl)
  4729. | TType (t,pl) as tf ->
  4730. (* recurse on type-type *)
  4731. if (snd t.t_path).[0] = '#' then make_type (follow tf) else tpath t.t_path t.t_module.m_path (List.map make_type pl)
  4732. | TAbstract (a,pl) ->
  4733. tpath a.a_path a.a_module.m_path (List.map make_type pl)
  4734. | TFun (args,ret) ->
  4735. CTFunction (List.map (fun (_,_,t) -> make_type t) args, make_type ret)
  4736. | TAnon a ->
  4737. begin match !(a.a_status) with
  4738. | Statics c -> tpath ([],"Class") ([],"Class") [tpath c.cl_path c.cl_path []]
  4739. | EnumStatics e -> tpath ([],"Enum") ([],"Enum") [tpath e.e_path e.e_path []]
  4740. | _ ->
  4741. CTAnonymous (PMap.foldi (fun _ f acc ->
  4742. {
  4743. cff_name = f.cf_name;
  4744. cff_kind = FVar (mk_ot f.cf_type,None);
  4745. cff_pos = f.cf_pos;
  4746. cff_doc = f.cf_doc;
  4747. cff_meta = f.cf_meta;
  4748. cff_access = [];
  4749. } :: acc
  4750. ) a.a_fields [])
  4751. end
  4752. | (TDynamic t2) as t ->
  4753. tpath ([],"Dynamic") ([],"Dynamic") (if t == t_dynamic then [] else [make_type t2])
  4754. | TLazy f ->
  4755. make_type ((!f)())
  4756. and mk_ot t =
  4757. match follow t with
  4758. | TMono _ -> None
  4759. | _ -> (try Some (make_type t) with Exit -> None)
  4760. let rec make_ast e =
  4761. let full_type_path t =
  4762. let mp,p = match t with
  4763. | TClassDecl c -> c.cl_module.m_path,c.cl_path
  4764. | TEnumDecl en -> en.e_module.m_path,en.e_path
  4765. | TAbstractDecl a -> a.a_module.m_path,a.a_path
  4766. | TTypeDecl t -> t.t_module.m_path,t.t_path
  4767. in
  4768. if snd mp = snd p then p else (fst mp) @ [snd mp],snd p
  4769. in
  4770. let mk_path (pack,name) p =
  4771. match List.rev pack with
  4772. | [] -> (EConst (Ident name),p)
  4773. | pl ->
  4774. let rec loop = function
  4775. | [] -> assert false
  4776. | [n] -> (EConst (Ident n),p)
  4777. | n :: l -> (EField (loop l, n),p)
  4778. in
  4779. (EField (loop pl,name),p)
  4780. in
  4781. let mk_const = function
  4782. | TInt i -> Int (Int32.to_string i)
  4783. | TFloat s -> Float s
  4784. | TString s -> String s
  4785. | TBool b -> Ident (if b then "true" else "false")
  4786. | TNull -> Ident "null"
  4787. | TThis -> Ident "this"
  4788. | TSuper -> Ident "super"
  4789. in
  4790. let mk_ident = function
  4791. | "`trace" -> Ident "trace"
  4792. | n -> Ident n
  4793. in
  4794. let eopt = function None -> None | Some e -> Some (make_ast e) in
  4795. ((match e.eexpr with
  4796. | TConst c ->
  4797. EConst (mk_const c)
  4798. | TLocal v -> EConst (mk_ident v.v_name)
  4799. | TArray (e1,e2) -> EArray (make_ast e1,make_ast e2)
  4800. | TBinop (op,e1,e2) -> EBinop (op, make_ast e1, make_ast e2)
  4801. | TField (e,f) -> EField (make_ast e, Type.field_name f)
  4802. | TTypeExpr t -> fst (mk_path (full_type_path t) e.epos)
  4803. | TParenthesis e -> EParenthesis (make_ast e)
  4804. | TObjectDecl fl -> EObjectDecl (List.map (fun (f,e) -> f, make_ast e) fl)
  4805. | TArrayDecl el -> EArrayDecl (List.map make_ast el)
  4806. | TCall (e,el) -> ECall (make_ast e,List.map make_ast el)
  4807. | TNew (c,pl,el) -> ENew ((match (try make_type (TInst (c,pl)) with Exit -> make_type (TInst (c,[]))) with CTPath p -> p | _ -> assert false),List.map make_ast el)
  4808. | TUnop (op,p,e) -> EUnop (op,p,make_ast e)
  4809. | TFunction f ->
  4810. let arg (v,c) = v.v_name, false, mk_ot v.v_type, (match c with None -> None | Some c -> Some (EConst (mk_const c),e.epos)) in
  4811. EFunction (None,{ f_params = []; f_args = List.map arg f.tf_args; f_type = mk_ot f.tf_type; f_expr = Some (make_ast f.tf_expr) })
  4812. | TVar (v,eo) ->
  4813. EVars ([v.v_name, mk_ot v.v_type, eopt eo])
  4814. | TBlock el -> EBlock (List.map make_ast el)
  4815. | TFor (v,it,e) ->
  4816. let ein = (EIn ((EConst (Ident v.v_name),it.epos),make_ast it),it.epos) in
  4817. EFor (ein,make_ast e)
  4818. | TIf (e,e1,e2) -> EIf (make_ast e,make_ast e1,eopt e2)
  4819. | TWhile (e1,e2,flag) -> EWhile (make_ast e1, make_ast e2, flag)
  4820. | TSwitch (e,cases,def) ->
  4821. let cases = List.map (fun (vl,e) ->
  4822. List.map make_ast vl,None,(match e.eexpr with TBlock [] -> None | _ -> Some (make_ast e))
  4823. ) cases in
  4824. let def = match eopt def with None -> None | Some (EBlock [],_) -> Some None | e -> Some e in
  4825. ESwitch (make_ast e,cases,def)
  4826. | TEnumParameter _ ->
  4827. (* these are considered complex, so the AST is handled in TMeta(Meta.Ast) *)
  4828. assert false
  4829. | TTry (e,catches) -> ETry (make_ast e,List.map (fun (v,e) -> v.v_name, (try make_type v.v_type with Exit -> assert false), make_ast e) catches)
  4830. | TReturn e -> EReturn (eopt e)
  4831. | TBreak -> EBreak
  4832. | TContinue -> EContinue
  4833. | TThrow e -> EThrow (make_ast e)
  4834. | TCast (e,t) ->
  4835. let t = (match t with
  4836. | None -> None
  4837. | Some t ->
  4838. let t = (match t with TClassDecl c -> TInst (c,[]) | TEnumDecl e -> TEnum (e,[]) | TTypeDecl t -> TType (t,[]) | TAbstractDecl a -> TAbstract (a,[])) in
  4839. Some (try make_type t with Exit -> assert false)
  4840. ) in
  4841. ECast (make_ast e,t)
  4842. | TMeta ((Meta.Ast,[e1,_],_),_) -> e1
  4843. | TMeta (m,e) -> EMeta(m,make_ast e))
  4844. ,e.epos)
  4845. ;;
  4846. make_ast_ref := make_ast;
  4847. make_complex_type_ref := make_type;
  4848. encode_complex_type_ref := encode_ctype;
  4849. enc_array_ref := enc_array;
  4850. dec_array_ref := dec_array;
  4851. encode_type_ref := encode_type;
  4852. decode_type_ref := decode_type;
  4853. encode_expr_ref := encode_expr;
  4854. decode_expr_ref := decode_expr;
  4855. encode_clref_ref := encode_clref;
  4856. enc_string_ref := enc_string;
  4857. enc_hash_ref := enc_hash;
  4858. encode_texpr_ref := encode_texpr;
  4859. decode_texpr_ref := decode_texpr;
  4860. encode_tvar_ref := encode_tvar;
  4861. decode_path_ref := decode_path;
  4862. decode_import_ref := decode_import;