interp.ml 148 KB

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